From 39f4d2b0b2c0e1f8fb9b7764cddd7ea379cc8a43 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Thu, 13 Dec 2012 18:11:19 +0400 Subject: [PATCH] IDEA-97472 Gradle: Provide jar-level library management facilities --- .../resources/i18n/GradleBundle.properties | 2 + plugins/gradle/src/META-INF/plugin.xml | 2 +- .../plugins/gradle/diff/GradleDiffUtil.java | 6 + .../GradleProjectStructureChangeVisitor.java | 9 +- ...eProjectStructureChangeVisitorAdapter.java | 11 +- .../diff/library/GradleJarPresenceChange.java | 26 ++ ...adleLibraryStructureChangesCalculator.java | 17 +- .../GradleMismatchedLibraryPathChange.java | 34 --- .../gradle/manage/GradleJarManager.java | 173 +++++++++++++ .../manage/GradleLocalNodeManageHelper.java | 46 +++- .../adjust/GradleContentRootSettings.java | 8 +- .../wizard/adjust/GradleJarSettings.java | 59 +++++ .../GradleLibraryDependencySettings.java | 2 +- .../wizard/adjust/GradleLibrarySettings.java | 51 +--- .../adjust/GradleProjectStructureFactory.java | 13 +- .../gradle/model/GradleEntityType.java | 3 +- .../model/gradle/GradleEntityVisitor.java | 1 + .../gradle/GradleEntityVisitorAdapter.java | 4 + .../gradle/model/gradle/GradleJar.java | 99 ++++++++ .../gradle/model/id/GradleEntityIdMapper.java | 5 + .../plugins/gradle/model/id/GradleJarId.java | 70 ++++++ .../gradle/model/id/GradleLibraryId.java | 7 +- .../sync/GradleProjectStructureHelper.java | 46 +++- .../sync/GradleProjectStructureTreeModel.java | 171 ++++++++++--- .../GradleConflictControlFactory.java | 4 - ...braryDependencyConflictControlFactory.java | 134 ---------- .../GradleProjectStructureNodeComparator.java | 10 +- .../GradleProjectStructureNodeDescriptor.java | 1 + .../plugins/gradle/util/GradleUtil.java | 41 +-- .../GradleLocalNodeManageHelperTest.groovy | 4 +- ...dleProjectStructureChangesModelTest.groovy | 234 ++++++++++-------- .../gradle/testutil/AbstractGradleTest.groovy | 48 +++- .../gradle/testutil/ChangeBuilder.groovy | 32 +-- .../testutil/GradleProjectBuilder.groovy | 1 + .../testutil/IntellijProjectBuilder.groovy | 8 +- .../testutil/ProjectStructureChecker.groovy | 25 +- .../util/RichTextControlBuilderTest.java | 6 +- 37 files changed, 954 insertions(+), 459 deletions(-) create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/diff/library/GradleJarPresenceChange.java delete mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/diff/library/GradleMismatchedLibraryPathChange.java create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleJarManager.java create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleJarSettings.java create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/model/gradle/GradleJar.java create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleJarId.java delete mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/sync/conflict/GradleLibraryDependencyConflictControlFactory.java diff --git a/plugins/gradle/resources/i18n/GradleBundle.properties b/plugins/gradle/resources/i18n/GradleBundle.properties index 0b55204bb070..7ff62347086e 100644 --- a/plugins/gradle/resources/i18n/GradleBundle.properties +++ b/plugins/gradle/resources/i18n/GradleBundle.properties @@ -34,6 +34,7 @@ gradle.import.structure.settings.label.scope=Scope: gradle.import.structure.settings.label.root.source=Source roots: gradle.import.structure.settings.label.root.test=Test roots: gradle.import.structure.settings.label.root.excluded=Excluded roots: +gradle.import.structure.settings.label.jar.path=Path: gradle.import.structure.settings.label.library.path.binary=Binary paths gradle.import.structure.settings.label.library.path.source=Source paths gradle.import.structure.settings.label.library.path.doc=Doc paths @@ -65,6 +66,7 @@ gradle.sync.change.type.confirmed=Confirmed settings diff gradle.sync.change.entity.type.module=module gradle.sync.change.entity.type.module.dependency=module dependency gradle.sync.change.entity.type.library.dependency=library dependency +gradle.sync.change.entity.type.jar=jar gradle.sync.change.dependency.scope=scope change for {0} gradle.sync.change.dependency.exported='exported' value change for {0} gradle.sync.change.library.path=library ''{0}'' binary path diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml index 7e5ff52fa7bb..41a8d54d8990 100644 --- a/plugins/gradle/src/META-INF/plugin.xml +++ b/plugins/gradle/src/META-INF/plugin.xml @@ -48,6 +48,7 @@ + @@ -63,7 +64,6 @@ - diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/GradleDiffUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/GradleDiffUtil.java index 9b53a42e0647..70dcd38a3819 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/GradleDiffUtil.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/GradleDiffUtil.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.gradle.diff.contentroot.GradleContentRootPresenceChange; import org.jetbrains.plugins.gradle.diff.dependency.GradleLibraryDependencyPresenceChange; import org.jetbrains.plugins.gradle.diff.dependency.GradleModuleDependencyPresenceChange; +import org.jetbrains.plugins.gradle.diff.library.GradleJarPresenceChange; import org.jetbrains.plugins.gradle.diff.module.GradleModulePresenceChange; import org.jetbrains.plugins.gradle.model.gradle.*; import org.jetbrains.plugins.gradle.model.intellij.IntellijEntityVisitor; @@ -68,6 +69,11 @@ public class GradleDiffUtil { // Don't show library nodes. } + @Override + public void visit(@NotNull GradleJar jar) { + context.register(new GradleJarPresenceChange(jar.getId(), null)); + } + @Override public void visit(@NotNull GradleModuleDependency dependency) { context.register(new GradleModuleDependencyPresenceChange(dependency, null)); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/GradleProjectStructureChangeVisitor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/GradleProjectStructureChangeVisitor.java index 8d989ccf0a30..aac9198ee534 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/GradleProjectStructureChangeVisitor.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/GradleProjectStructureChangeVisitor.java @@ -17,11 +17,8 @@ package org.jetbrains.plugins.gradle.diff; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.gradle.diff.contentroot.GradleContentRootPresenceChange; -import org.jetbrains.plugins.gradle.diff.dependency.GradleDependencyExportedChange; -import org.jetbrains.plugins.gradle.diff.dependency.GradleDependencyScopeChange; -import org.jetbrains.plugins.gradle.diff.dependency.GradleLibraryDependencyPresenceChange; -import org.jetbrains.plugins.gradle.diff.dependency.GradleModuleDependencyPresenceChange; -import org.jetbrains.plugins.gradle.diff.library.GradleMismatchedLibraryPathChange; +import org.jetbrains.plugins.gradle.diff.dependency.*; +import org.jetbrains.plugins.gradle.diff.library.GradleJarPresenceChange; import org.jetbrains.plugins.gradle.diff.module.GradleModulePresenceChange; import org.jetbrains.plugins.gradle.diff.project.GradleLanguageLevelChange; import org.jetbrains.plugins.gradle.diff.project.GradleProjectRenameChange; @@ -38,8 +35,8 @@ public interface GradleProjectStructureChangeVisitor { void visit(@NotNull GradleModulePresenceChange change); void visit(@NotNull GradleContentRootPresenceChange change); void visit(@NotNull GradleLibraryDependencyPresenceChange change); + void visit(@NotNull GradleJarPresenceChange change); void visit(@NotNull GradleModuleDependencyPresenceChange change); - void visit(@NotNull GradleMismatchedLibraryPathChange change); void visit(@NotNull GradleDependencyScopeChange change); void visit(@NotNull GradleDependencyExportedChange change); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/GradleProjectStructureChangeVisitorAdapter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/GradleProjectStructureChangeVisitorAdapter.java index 443527ededa1..e5ba831602ac 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/GradleProjectStructureChangeVisitorAdapter.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/GradleProjectStructureChangeVisitorAdapter.java @@ -2,11 +2,8 @@ package org.jetbrains.plugins.gradle.diff; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.gradle.diff.contentroot.GradleContentRootPresenceChange; -import org.jetbrains.plugins.gradle.diff.dependency.GradleDependencyExportedChange; -import org.jetbrains.plugins.gradle.diff.dependency.GradleDependencyScopeChange; -import org.jetbrains.plugins.gradle.diff.dependency.GradleLibraryDependencyPresenceChange; -import org.jetbrains.plugins.gradle.diff.dependency.GradleModuleDependencyPresenceChange; -import org.jetbrains.plugins.gradle.diff.library.GradleMismatchedLibraryPathChange; +import org.jetbrains.plugins.gradle.diff.dependency.*; +import org.jetbrains.plugins.gradle.diff.library.GradleJarPresenceChange; import org.jetbrains.plugins.gradle.diff.module.GradleModulePresenceChange; import org.jetbrains.plugins.gradle.diff.project.GradleLanguageLevelChange; import org.jetbrains.plugins.gradle.diff.project.GradleProjectRenameChange; @@ -37,11 +34,11 @@ public abstract class GradleProjectStructureChangeVisitorAdapter implements Grad } @Override - public void visit(@NotNull GradleModuleDependencyPresenceChange change) { + public void visit(@NotNull GradleJarPresenceChange change) { } @Override - public void visit(@NotNull GradleMismatchedLibraryPathChange change) { + public void visit(@NotNull GradleModuleDependencyPresenceChange change) { } @Override diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/library/GradleJarPresenceChange.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/library/GradleJarPresenceChange.java new file mode 100644 index 000000000000..9de59ea9ea93 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/library/GradleJarPresenceChange.java @@ -0,0 +1,26 @@ +package org.jetbrains.plugins.gradle.diff.library; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.gradle.diff.GradleAbstractEntityPresenceChange; +import org.jetbrains.plugins.gradle.diff.GradleProjectStructureChangeVisitor; +import org.jetbrains.plugins.gradle.model.id.GradleJarId; +import org.jetbrains.plugins.gradle.util.GradleBundle; + +/** + * @author Denis Zhdanov + * @since 12/11/12 7:52 PM + */ +public class GradleJarPresenceChange extends GradleAbstractEntityPresenceChange { + + public GradleJarPresenceChange(@Nullable GradleJarId gradleEntity, + @Nullable GradleJarId intellijEntity) throws IllegalArgumentException + { + super(GradleBundle.message("gradle.sync.change.entity.type.jar"), gradleEntity, intellijEntity); + } + + @Override + public void invite(@NotNull GradleProjectStructureChangeVisitor visitor) { + visitor.visit(this); + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/library/GradleLibraryStructureChangesCalculator.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/library/GradleLibraryStructureChangesCalculator.java index 77f54b8e7eb9..cb00e9726044 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/library/GradleLibraryStructureChangesCalculator.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/library/GradleLibraryStructureChangesCalculator.java @@ -7,8 +7,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.gradle.config.PlatformFacade; import org.jetbrains.plugins.gradle.diff.GradleChangesCalculationContext; import org.jetbrains.plugins.gradle.diff.GradleStructureChangesCalculator; +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.GradleJarId; +import org.jetbrains.plugins.gradle.model.id.GradleLibraryId; import org.jetbrains.plugins.gradle.util.GradleUtil; import java.util.HashSet; @@ -40,8 +43,18 @@ public class GradleLibraryStructureChangesCalculator implements GradleStructureC } } - if (!gradleBinaryPaths.equals(intellijBinaryPaths)) { - context.register(new GradleMismatchedLibraryPathChange(intellijEntity, gradleBinaryPaths, intellijBinaryPaths)); + if (!gradleBinaryPaths.isEmpty()) { + GradleLibraryId libraryId = new GradleLibraryId(GradleEntityOwner.GRADLE, gradleEntity.getName()); + for (String path : gradleBinaryPaths) { + context.register(new GradleJarPresenceChange(new GradleJarId(path, libraryId), null)); + } + } + + if (!intellijBinaryPaths.isEmpty()) { + GradleLibraryId libraryId = new GradleLibraryId(GradleEntityOwner.INTELLIJ, GradleUtil.getLibraryName(intellijEntity)); + for (String path : intellijBinaryPaths) { + context.register(new GradleJarPresenceChange(null, new GradleJarId(path, libraryId))); + } } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/library/GradleMismatchedLibraryPathChange.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/library/GradleMismatchedLibraryPathChange.java deleted file mode 100644 index e86448943764..000000000000 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/library/GradleMismatchedLibraryPathChange.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.jetbrains.plugins.gradle.diff.library; - -import com.intellij.openapi.roots.libraries.Library; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.gradle.diff.GradleAbstractConflictingPropertyChange; -import org.jetbrains.plugins.gradle.diff.GradleProjectStructureChangeVisitor; -import org.jetbrains.plugins.gradle.model.id.GradleEntityIdMapper; -import org.jetbrains.plugins.gradle.util.GradleBundle; -import org.jetbrains.plugins.gradle.util.GradleUtil; - -import java.util.Set; - -/** - * @author Denis Zhdanov - * @since 2/2/12 1:32 PM - */ -public class GradleMismatchedLibraryPathChange extends GradleAbstractConflictingPropertyChange> { - - public GradleMismatchedLibraryPathChange(@NotNull Library entity, - @NotNull Set gradleValue, - @NotNull Set intellijValue) - throws IllegalArgumentException - { - super(GradleEntityIdMapper.mapEntityToId(entity), - GradleBundle.message("gradle.sync.change.library.path", GradleUtil.getLibraryName(entity)), - gradleValue, - intellijValue); - } - - @Override - public void invite(@NotNull GradleProjectStructureChangeVisitor visitor) { - visitor.visit(this); - } -} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleJarManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleJarManager.java new file mode 100644 index 000000000000..a3aa33580708 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleJarManager.java @@ -0,0 +1,173 @@ +/* + * Copyright 2000-2012 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.manage; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.libraries.Library; +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.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.id.GradleLibraryId; +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; + +/** + * @author Denis Zhdanov + * @since 12/13/12 1:04 PM + */ +public class GradleJarManager { + + @NotNull private final PlatformFacade myPlatformFacade; + + public GradleJarManager(@NotNull PlatformFacade facade) { + myPlatformFacade = facade; + } + + public void importJar(@NotNull final GradleJar jar, @NotNull final Project project) { + GradleUtil.executeProjectChangeAction(project, jar, new Runnable() { + @Override + public void run() { + LibraryTable table = myPlatformFacade.getProjectLibraryTable(project); + Library library = table.getLibraryByName(jar.getLibraryId().getLibraryName()); + if (library == null) { + return; + } + Library.ModifiableModel model = library.getModifiableModel(); + try { + for (VirtualFile file : model.getFiles(OrderRootType.CLASSES)) { + if (jar.getPath().equals(file.getPath())) { + 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, OrderRootType.CLASSES); + } + 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, OrderRootType.CLASSES); + } + } + finally { + model.commit(); + } + } + }); + } + + public void removeJars(@NotNull Collection jars, @NotNull Project project) { + if (jars.isEmpty()) { + return; + } + Map> jarsByLibraries = ContainerUtilRt.newHashMap(); + for (GradleJar jar : jars) { + List list = jarsByLibraries.get(jar.getLibraryId()); + if (list == null) { + jarsByLibraries.put(jar.getLibraryId(), list = ContainerUtilRt.newArrayList()); + } + list.add(jar); + } + + LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(project); + for (Map.Entry> entry : jarsByLibraries.entrySet()) { + Library library = libraryTable.getLibraryByName(entry.getKey().getLibraryName()); + if (library == null) { + continue; + } + Set libraryJars = ContainerUtilRt.newHashSet(entry.getValue()); + for (GradleJar jar : entry.getValue()) { + boolean valid = false; + for (VirtualFile file : library.getFiles(OrderRootType.CLASSES)) { + if (jar.getPath().equals(GradleUtil.getLocalFileSystemPath(file))) { + valid = true; + break; + } + } + if (!valid) { + libraryJars.remove(jar); + } + } + + if (!libraryJars.isEmpty()) { + removeLibraryJars(libraryJars, project); + } + } + } + + /** + * Removes given jars from IDE project structure assuming that they belong to the same library. + * + * @param jars jars to remove + * @param project current project + */ + private void removeLibraryJars(@NotNull final Set jars, @NotNull final Project project) { + GradleUtil.executeProjectChangeAction(project, jars, new Runnable() { + @Override + public void run() { + LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(project); + GradleLibraryId libraryId = jars.iterator().next().getLibraryId(); + Library library = libraryTable.getLibraryByName(libraryId.getLibraryName()); + if (library == null) { + return; + } + Set pathsToRemove = ContainerUtil.map2Set(jars, new Function() { + @Override + public String fun(GradleJar jar) { + return jar.getPath(); + } + }); + Library.ModifiableModel model = library.getModifiableModel(); + try { + for (VirtualFile file : model.getFiles(OrderRootType.CLASSES)) { + if (pathsToRemove.contains(GradleUtil.getLocalFileSystemPath(file))) { + model.removeRoot(file.getUrl(), OrderRootType.CLASSES); + } + } + } + finally { + model.commit(); + } + } + }); + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleLocalNodeManageHelper.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleLocalNodeManageHelper.java index deb93a2285e4..497671c1eadf 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleLocalNodeManageHelper.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleLocalNodeManageHelper.java @@ -6,6 +6,7 @@ import com.intellij.openapi.roots.ExportableOrderEntry; import com.intellij.openapi.roots.LibraryOrderEntry; import com.intellij.openapi.roots.ModuleOrderEntry; import com.intellij.openapi.roots.libraries.Library; +import com.intellij.util.containers.ContainerUtilRt; import com.intellij.util.containers.Stack; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.gradle.config.GradleTextAttributes; @@ -55,6 +56,7 @@ public class GradleLocalNodeManageHelper { @NotNull private final GradleEntityIdMapper myIdMapper; @NotNull private final GradleModuleManager myModuleManager; @NotNull private final GradleLibraryManager myLibraryManager; + @NotNull private final GradleJarManager myJarManager; @NotNull private final GradleDependencyManager myModuleDependencyManager; @NotNull private final GradleContentRootManager myContentRootManager; @@ -62,12 +64,14 @@ public class GradleLocalNodeManageHelper { @NotNull GradleEntityIdMapper idMapper, @NotNull GradleModuleManager moduleManager, @NotNull GradleLibraryManager libraryManager, + @NotNull GradleJarManager jarManager, @NotNull GradleDependencyManager moduleDependencyManager, @NotNull GradleContentRootManager contentRootManager) { myProjectStructureHelper = projectStructureHelper; myIdMapper = idMapper; myModuleManager = moduleManager; + myJarManager = jarManager; myModuleDependencyManager = moduleDependencyManager; myLibraryManager = libraryManager; myContentRootManager = contentRootManager; @@ -232,6 +236,11 @@ public class GradleLocalNodeManageHelper { myLibraryManager.importLibrary(library, myProjectStructureHelper.getProject()); } + @Override + public void visit(@NotNull GradleJar jar) { + myJarManager.importJar(jar, myProjectStructureHelper.getProject()); + } + @Override public void visit(@NotNull GradleModuleDependency dependency) { final Module module = myProjectStructureHelper.findIntellijModule(dependency.getOwnerModule()); @@ -251,11 +260,12 @@ public class GradleLocalNodeManageHelper { } public void removeNodes(@NotNull Collection> nodes) { - final List libraries = new ArrayList(); - final List modules = new ArrayList(); - final List contentRoots = new ArrayList(); - final List dependencies = new ArrayList(); - IntellijEntityVisitor visitor = new IntellijEntityVisitor() { + final List libraries = ContainerUtilRt.newArrayList(); + final List modules = ContainerUtilRt.newArrayList(); + final List contentRoots = ContainerUtilRt.newArrayList(); + final List dependencies = ContainerUtilRt.newArrayList(); + final List jars = ContainerUtilRt.newArrayList(); + IntellijEntityVisitor intellijVisitor = new IntellijEntityVisitor() { @Override public void visit(@NotNull Project project) { } @Override public void visit(@NotNull Module module) { modules.add(module); } @Override public void visit(@NotNull ModuleAwareContentRoot contentRoot) { contentRoots.add(contentRoot); } @@ -263,6 +273,13 @@ public class GradleLocalNodeManageHelper { @Override public void visit(@NotNull ModuleOrderEntry moduleDependency) { dependencies.add(moduleDependency); } @Override public void visit(@NotNull Library library) { libraries.add(library); } }; + GradleEntityVisitor gradleVisitor = new GradleEntityVisitorAdapter() { + @Override + public void visit(@NotNull GradleJar jar) { + jars.add(jar); + } + }; + for (GradleProjectStructureNode node : nodes) { GradleProjectStructureNodeDescriptor descriptor = node.getDescriptor(); @@ -270,11 +287,15 @@ public class GradleLocalNodeManageHelper { continue; } Object entity = myIdMapper.mapIdToEntity(descriptor.getElement()); - if (entity != null) { - GradleUtil.dispatch(entity, visitor); + if (entity instanceof GradleEntity) { + ((GradleEntity)entity).invite(gradleVisitor); + } + else if (entity != null) { + GradleUtil.dispatch(entity, intellijVisitor); } } + myJarManager.removeJars(jars, myProjectStructureHelper.getProject()); myContentRootManager.removeContentRoots(contentRoots); myModuleDependencyManager.removeDependencies(dependencies); myModuleManager.removeModules(modules); @@ -284,10 +305,11 @@ public class GradleLocalNodeManageHelper { private class Context { - public final Set modules = new HashSet(); - public final Set contentRoots = new HashSet(); - public final Set libraries = new HashSet(); - public final Set dependencies = new HashSet(); + public final Set modules = ContainerUtilRt.newHashSet(); + public final Set contentRoots = ContainerUtilRt.newHashSet(); + public final Set libraries = ContainerUtilRt.newHashSet(); + public final Set jars = ContainerUtilRt.newHashSet(); + public final Set dependencies = ContainerUtilRt.newHashSet(); public final CollectingVisitor gradleVisitor = new CollectingVisitor(this); public boolean recursive; @@ -297,6 +319,7 @@ public class GradleLocalNodeManageHelper { result.addAll(modules); result.addAll(contentRoots); result.addAll(libraries); + result.addAll(jars); result.addAll(dependencies); return result; } @@ -315,5 +338,6 @@ public class GradleLocalNodeManageHelper { @Override public void visit(@NotNull GradleLibrary library) { /* Assuming that a library may be imported only as a dependency */ } @Override public void visit(@NotNull GradleModuleDependency dependency) { collectModuleDependencyEntities(dependency, myContext); } @Override public void visit(@NotNull GradleLibraryDependency dependency) { collectLibraryDependencyEntities(dependency, myContext); } + @Override public void visit(@NotNull GradleJar jar) { myContext.jars.add(jar); } } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleContentRootSettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleContentRootSettings.java index ddbc06d0926e..7718822470f2 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleContentRootSettings.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleContentRootSettings.java @@ -24,8 +24,8 @@ public class GradleContentRootSettings implements GradleProjectStructureNodeSett ROOT_TYPE_TITLES.put(SourceType.EXCLUDED, GradleBundle.message("gradle.import.structure.settings.label.root.excluded")); assert ROOT_TYPE_TITLES.size() == SourceType.values().length; } - - private final JComponent myComponent; + + @NotNull private final JComponent myComponent; public GradleContentRootSettings(@NotNull GradleContentRoot contentRoot) { GradleProjectSettingsBuilder builder = new GradleProjectSettingsBuilder(); @@ -33,7 +33,7 @@ public class GradleContentRootSettings implements GradleProjectStructureNodeSett Collection paths = contentRoot.getPaths(sourceType); if (paths.isEmpty()) { continue; - } + } builder.add(new JLabel(ROOT_TYPE_TITLES.get(sourceType))); for (String path : paths) { NamePathComponent component = new NamePathComponent("", " ", "", "", false); @@ -45,7 +45,7 @@ public class GradleContentRootSettings implements GradleProjectStructureNodeSett } myComponent = builder.build(); } - + @Override public boolean validate() { return true; diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleJarSettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleJarSettings.java new file mode 100644 index 000000000000..9122182129cb --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleJarSettings.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2012 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.manage.wizard.adjust; + +import com.intellij.ide.util.projectWizard.NamePathComponent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.gradle.model.gradle.GradleJar; +import org.jetbrains.plugins.gradle.util.GradleBundle; + +import javax.swing.*; + +/** + * @author Denis Zhdanov + * @since 12/12/12 2:16 PM + */ +public class GradleJarSettings implements GradleProjectStructureNodeSettings { + + @NotNull private final JComponent myComponent; + + public GradleJarSettings(@NotNull GradleJar jar) { + GradleProjectSettingsBuilder builder = new GradleProjectSettingsBuilder(); + builder.add(new JLabel(GradleBundle.message("gradle.import.structure.settings.label.jar.path"))); + NamePathComponent component = new NamePathComponent("", " ", "", "", false); + component.setNameComponentVisible(false); + component.setPath(jar.getPath()); + component.getPathPanel().setEditable(false); + builder.add(component, GradleProjectSettingsBuilder.InsetSize.SMALL); + + myComponent = builder.build(); + } + + @Override + public boolean validate() { + return true; + } + + @Override + public void refresh() { + } + + @NotNull + @Override + public JComponent getComponent() { + return myComponent; + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleLibraryDependencySettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleLibraryDependencySettings.java index ce2449fcf023..2de7c96f022c 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleLibraryDependencySettings.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleLibraryDependencySettings.java @@ -18,7 +18,7 @@ public class GradleLibraryDependencySettings implements GradleProjectStructureNo private final JComponent myComponent; public GradleLibraryDependencySettings(@NotNull GradleLibraryDependency dependency) { - myLibrarySettings = new GradleLibrarySettings(dependency.getTarget()); + myLibrarySettings = new GradleLibrarySettings(); GradleProjectSettingsBuilder builder = new GradleProjectSettingsBuilder(); builder.add(myLibrarySettings.getComponent(), GradleProjectSettingsBuilder.InsetSize.NONE); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleLibrarySettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleLibrarySettings.java index c8532daace6b..ad00e7e97554 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleLibrarySettings.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleLibrarySettings.java @@ -1,15 +1,8 @@ package org.jetbrains.plugins.gradle.manage.wizard.adjust; -import com.intellij.ide.util.projectWizard.NamePathComponent; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.gradle.model.gradle.GradleLibrary; -import org.jetbrains.plugins.gradle.model.gradle.LibraryPathType; -import org.jetbrains.plugins.gradle.util.GradleBundle; import javax.swing.*; -import java.util.EnumMap; -import java.util.Map; -import java.util.Set; /** * @author Denis Zhdanov @@ -17,51 +10,19 @@ import java.util.Set; */ public class GradleLibrarySettings implements GradleProjectStructureNodeSettings { - private static final Map PATH_TITLES = new EnumMap(LibraryPathType.class); - static { - PATH_TITLES.put(LibraryPathType.BINARY, GradleBundle.message("gradle.import.structure.settings.label.library.path.binary")); - PATH_TITLES.put(LibraryPathType.SOURCE, GradleBundle.message("gradle.import.structure.settings.label.library.path.source")); - PATH_TITLES.put(LibraryPathType.DOC, GradleBundle.message("gradle.import.structure.settings.label.library.path.doc")); - assert PATH_TITLES.size() == LibraryPathType.values().length; + private final JComponent myComponent; + + public GradleLibrarySettings() { + myComponent = new JPanel(); } - - private final GradleLibrary myLibrary; - private final JComponent myComponent; - private final JTextField myNameControl; - - public GradleLibrarySettings(@NotNull GradleLibrary library) { - myLibrary = library; - GradleProjectSettingsBuilder builder = new GradleProjectSettingsBuilder(); - myNameControl = GradleAdjustImportSettingsUtil.configureNameControl(builder, library); - setupLibraryPaths(builder); - myComponent = builder.build(); - } - - private void setupLibraryPaths(@NotNull GradleProjectSettingsBuilder builder) { - for (LibraryPathType pathType : LibraryPathType.values()) { - Set paths = myLibrary.getPaths(pathType); - if (paths.isEmpty()) { - continue; - } - builder.add(new JLabel(PATH_TITLES.get(pathType))); - for (String path : paths) { - NamePathComponent component = new NamePathComponent("", " ", "", "", false); - component.setNameComponentVisible(false); - component.setPath(path); - component.getPathPanel().setEditable(false); - builder.add(component, GradleProjectSettingsBuilder.InsetSize.SMALL); - } - } - } - + @Override public boolean validate() { - return GradleAdjustImportSettingsUtil.validate(myLibrary, myNameControl); + return true; } @Override public void refresh() { - myNameControl.setText(myLibrary.getName()); } @NotNull diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleProjectStructureFactory.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleProjectStructureFactory.java index 2d8193353ec2..21071661df90 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleProjectStructureFactory.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleProjectStructureFactory.java @@ -55,6 +55,11 @@ public class GradleProjectStructureFactory { text.set(library.getName()); } + @Override + public void visit(@NotNull GradleJar jar) { + text.set(GradleUtil.extractNameFromPath(jar.getPath())); + } + @Override public void visit(@NotNull GradleModuleDependency dependency) { visit(dependency.getTarget()); @@ -95,8 +100,12 @@ public class GradleProjectStructureFactory { @Override public void visit(@NotNull GradleLibrary library) { - setupController(library, treeModel, treeNodes); - result.set(new GradleLibrarySettings(library)); + result.set(new GradleLibrarySettings()); + } + + @Override + public void visit(@NotNull GradleJar jar) { + result.set(new GradleJarSettings(jar)); } @Override diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleEntityType.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleEntityType.java index f2ae3114d598..7bcab27a1804 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleEntityType.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleEntityType.java @@ -12,7 +12,8 @@ import javax.swing.*; */ public enum GradleEntityType { PROJECT(GradleIcons.PROJECT_ICON), MODULE(AllIcons.Nodes.Module), MODULE_DEPENDENCY(AllIcons.Nodes.Module), - LIBRARY(AllIcons.Nodes.PpLib), LIBRARY_DEPENDENCY(AllIcons.Nodes.PpLib), CONTENT_ROOT(null), SYNTHETIC(null); + LIBRARY(AllIcons.Nodes.PpLib), LIBRARY_DEPENDENCY(AllIcons.Nodes.PpLib), CONTENT_ROOT(null), SYNTHETIC(null), + JAR(AllIcons.FileTypes.Archive); @Nullable private final Icon myIcon; diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/gradle/GradleEntityVisitor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/gradle/GradleEntityVisitor.java index 10db116d510e..5c54b04498ac 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/gradle/GradleEntityVisitor.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/gradle/GradleEntityVisitor.java @@ -12,6 +12,7 @@ public interface GradleEntityVisitor { void visit(@NotNull GradleModule module); void visit(@NotNull GradleContentRoot contentRoot); void visit(@NotNull GradleLibrary library); + void visit(@NotNull GradleJar jar); void visit(@NotNull GradleModuleDependency dependency); void visit(@NotNull GradleLibraryDependency dependency); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/gradle/GradleEntityVisitorAdapter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/gradle/GradleEntityVisitorAdapter.java index 3f23ff4c63ee..74223685edde 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/gradle/GradleEntityVisitorAdapter.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/gradle/GradleEntityVisitorAdapter.java @@ -23,6 +23,10 @@ public abstract class GradleEntityVisitorAdapter implements GradleEntityVisitor public void visit(@NotNull GradleLibrary library) { } + @Override + public void visit(@NotNull GradleJar jar) { + } + @Override public void visit(@NotNull GradleModuleDependency dependency) { } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/gradle/GradleJar.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/gradle/GradleJar.java new file mode 100644 index 000000000000..b0c4a7305176 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/gradle/GradleJar.java @@ -0,0 +1,99 @@ +package org.jetbrains.plugins.gradle.model.gradle; + +import com.intellij.openapi.roots.libraries.Library; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.gradle.model.GradleEntityOwner; +import org.jetbrains.plugins.gradle.model.id.GradleJarId; +import org.jetbrains.plugins.gradle.model.id.GradleLibraryId; +import org.jetbrains.plugins.gradle.util.GradleUtil; + +/** + * @author Denis Zhdanov + * @since 12/11/12 3:07 PM + */ +public class GradleJar extends AbstractNamedGradleEntity { + + @NotNull private final String myPath; + + @Nullable private final Library myIntellijLibrary; + @Nullable private final GradleLibrary myGradleLibrary; + + public GradleJar(@NotNull String path, @Nullable Library intellijLibrary, @Nullable GradleLibrary gradleLibrary) { + super(GradleUtil.extractNameFromPath(path)); + assert intellijLibrary == null ^ gradleLibrary == null; + myPath = path; + myIntellijLibrary = intellijLibrary; + myGradleLibrary = gradleLibrary; + } + + @NotNull + public String getPath() { + return myPath; + } + + @NotNull + public GradleJarId getId() { + return new GradleJarId(myPath, getLibraryId()); + } + + @NotNull + public GradleLibraryId getLibraryId() { + if (myIntellijLibrary != null) { + return new GradleLibraryId(GradleEntityOwner.INTELLIJ, GradleUtil.getLibraryName(myIntellijLibrary)); + } + assert myGradleLibrary != null; + return new GradleLibraryId(GradleEntityOwner.GRADLE, myGradleLibrary.getName()); + } + + @Override + public void invite(@NotNull GradleEntityVisitor visitor) { + visitor.visit(this); + } + + @NotNull + @Override + public GradleJar clone(@NotNull GradleEntityCloneContext context) { + return new GradleJar(myPath, myIntellijLibrary, myGradleLibrary == null ? null : context.getLibrary(myGradleLibrary)); + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + myPath.hashCode(); + result = 31 * result + (myIntellijLibrary != null ? myIntellijLibrary.hashCode() : 0); + result = 31 * result + (myGradleLibrary != null ? myGradleLibrary.hashCode() : 0); + return result; + } + + @Override + public boolean equals(Object o) { + if (!super.equals(o)) return false; + + GradleJar that = (GradleJar)o; + + if (!myPath.equals(that.myPath)) return false; + if (myGradleLibrary != null ? !myGradleLibrary.equals(that.myGradleLibrary) : that.myGradleLibrary != null) return false; + if (myIntellijLibrary == null && that.myIntellijLibrary != null) { + return false; + } + else if (myIntellijLibrary != null) { + if (that.myIntellijLibrary == null) { + return false; + } + else if (!GradleUtil.getLibraryName(myIntellijLibrary).equals(GradleUtil.getLibraryName(that.myIntellijLibrary))) { + return false; + } + } + return true; + } + + @SuppressWarnings("ConstantConditions") + @Override + public String toString() { + return String.format( + "jar at '%s'. Belongs to library '%s'", + myPath, myIntellijLibrary == null ? myGradleLibrary.getName() : GradleUtil.getLibraryName(myIntellijLibrary) + ); + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleEntityIdMapper.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleEntityIdMapper.java index a78a94f1ea26..2794bd49137c 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleEntityIdMapper.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleEntityIdMapper.java @@ -75,6 +75,11 @@ public class GradleEntityIdMapper { public void visit(@NotNull GradleLibrary library) { result.set(new GradleLibraryId(GradleEntityOwner.GRADLE, library.getName())); } + + @Override + public void visit(@NotNull GradleJar jar) { + result.set(jar.getId()); + } }); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleJarId.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleJarId.java new file mode 100644 index 000000000000..5c0d1917cac1 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleJarId.java @@ -0,0 +1,70 @@ +package org.jetbrains.plugins.gradle.model.id; + +import com.intellij.openapi.roots.libraries.Library; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.gradle.model.GradleEntityType; +import org.jetbrains.plugins.gradle.model.gradle.GradleJar; +import org.jetbrains.plugins.gradle.model.gradle.GradleLibrary; +import org.jetbrains.plugins.gradle.util.GradleProjectStructureContext; + +/** + * @author Denis Zhdanov + * @since 12/11/12 3:04 PM + */ +public class GradleJarId extends GradleAbstractEntityId { + + @NotNull private final String myPath; + @NotNull private final GradleLibraryId myLibraryId; + + public GradleJarId(@NotNull String path, @NotNull GradleLibraryId libraryId) { + super(GradleEntityType.JAR, libraryId.getOwner()); + myPath = path; + myLibraryId = libraryId; + } + + @NotNull + public String getPath() { + return myPath; + } + + @NotNull + public GradleLibraryId getLibraryId() { + return myLibraryId; + } + + @Nullable + @Override + public Object mapToEntity(@NotNull GradleProjectStructureContext context) { + Library intellijLibrary = context.getProjectStructureHelper().findIntellijLibrary(myLibraryId.getLibraryName(), myPath); + if (intellijLibrary != null) { + return new GradleJar(myPath, intellijLibrary, null); + } + + GradleLibrary gradleLibrary = context.getProjectStructureHelper().findGradleLibrary(myLibraryId.getLibraryName(), myPath); + if (gradleLibrary != null) { + return new GradleJar(myPath, null, gradleLibrary); + } + return null; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + myPath.hashCode(); + return result; + } + + @Override + public boolean equals(Object o) { + if (!super.equals(o)) return false; + + GradleJarId that = (GradleJarId)o; + return myPath.equals(that.myPath); + } + + @Override + public String toString() { + return String.format("jar '%s'", myPath); + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleLibraryId.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleLibraryId.java index 248539a07717..2024b0d2da00 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleLibraryId.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleLibraryId.java @@ -17,7 +17,12 @@ public class GradleLibraryId extends GradleAbstractEntityId { super(GradleEntityType.LIBRARY, owner); myLibraryName = libraryName; } - + + @NotNull + public String getLibraryName() { + return myLibraryName; + } + @Override public Object mapToEntity(@NotNull GradleProjectStructureContext context) { switch (getOwner()) { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureHelper.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureHelper.java index 8a0b05240b37..b380cafb198b 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureHelper.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureHelper.java @@ -12,9 +12,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.config.PlatformFacade; import org.jetbrains.plugins.gradle.model.gradle.*; -import org.jetbrains.plugins.gradle.model.id.GradleContentRootId; -import org.jetbrains.plugins.gradle.model.id.GradleLibraryDependencyId; -import org.jetbrains.plugins.gradle.model.id.GradleModuleDependencyId; +import org.jetbrains.plugins.gradle.model.id.*; import org.jetbrains.plugins.gradle.model.intellij.ModuleAwareContentRoot; import org.jetbrains.plugins.gradle.util.GradleUtil; @@ -148,6 +146,20 @@ public class GradleProjectStructureHelper extends AbstractProjectComponent { } return null; } + + @Nullable + public Library findIntellijLibrary(@NotNull String libraryName, @NotNull String jarPath) { + Library library = findIntellijLibrary(libraryName); + if (library == null) { + return null; + } + for (VirtualFile file : library.getFiles(OrderRootType.CLASSES)) { + if (jarPath.equals(GradleUtil.getLocalFileSystemPath(file))) { + return library; + } + } + return null; + } @Nullable public LibraryOrderEntry findIntellijLibraryDependency(@NotNull final String moduleName, @NotNull final String libraryName) { @@ -189,6 +201,11 @@ public class GradleProjectStructureHelper extends AbstractProjectComponent { return null; } + @Nullable + public GradleLibrary findGradleLibrary(@NotNull final GradleLibraryId id) { + return findGradleLibrary(id.getLibraryName()); + } + @Nullable public GradleLibrary findGradleLibrary(@NotNull final String libraryName) { final GradleProject project = myModel.getGradleProject(); @@ -202,6 +219,15 @@ public class GradleProjectStructureHelper extends AbstractProjectComponent { } return null; } + + @Nullable + public GradleLibrary findGradleLibrary(@NotNull String libraryName, @NotNull String jarPath) { + GradleLibrary library = findGradleLibrary(libraryName); + if (library == null) { + return null; + } + return library.getPaths(LibraryPathType.BINARY).contains(jarPath) ? library : null; + } @Nullable public GradleLibraryDependency findGradleLibraryDependency(@NotNull final String moduleName, @NotNull final String libraryName) { @@ -294,4 +320,18 @@ public class GradleProjectStructureHelper extends AbstractProjectComponent { } return null; } + + @Nullable + public GradleJar findIntellijJar(@NotNull GradleJarId jarId) { + Library library = findIntellijLibrary(jarId.getLibraryId().getLibraryName()); + if (library == null) { + return null; + } + for (VirtualFile file : library.getFiles(OrderRootType.CLASSES)) { + if (jarId.getPath().equals(GradleUtil.getLocalFileSystemPath(file))) { + return new GradleJar(jarId.getPath(), library, null); + } + } + return null; + } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureTreeModel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureTreeModel.java index 27f70f50c662..4279aeaa4e65 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureTreeModel.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureTreeModel.java @@ -4,8 +4,12 @@ import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.ContainerUtilRt; import com.intellij.util.containers.hash.HashMap; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -22,12 +26,14 @@ import org.jetbrains.plugins.gradle.diff.dependency.GradleDependencyExportedChan import org.jetbrains.plugins.gradle.diff.dependency.GradleDependencyScopeChange; import org.jetbrains.plugins.gradle.diff.dependency.GradleLibraryDependencyPresenceChange; import org.jetbrains.plugins.gradle.diff.dependency.GradleModuleDependencyPresenceChange; -import org.jetbrains.plugins.gradle.diff.library.GradleMismatchedLibraryPathChange; +import org.jetbrains.plugins.gradle.diff.library.GradleJarPresenceChange; import org.jetbrains.plugins.gradle.diff.module.GradleModulePresenceChange; import org.jetbrains.plugins.gradle.diff.project.GradleLanguageLevelChange; import org.jetbrains.plugins.gradle.diff.project.GradleProjectRenameChange; import org.jetbrains.plugins.gradle.model.GradleEntityOwner; +import org.jetbrains.plugins.gradle.model.gradle.GradleLibrary; import org.jetbrains.plugins.gradle.model.gradle.GradleModule; +import org.jetbrains.plugins.gradle.model.gradle.LibraryPathType; import org.jetbrains.plugins.gradle.model.id.*; import org.jetbrains.plugins.gradle.model.intellij.ModuleAwareContentRoot; import org.jetbrains.plugins.gradle.ui.GradleProjectStructureNode; @@ -54,19 +60,7 @@ import java.util.*; public class GradleProjectStructureTreeModel extends DefaultTreeModel { private static final Function SELF_MAPPER = new Function.Self(); - - private static final Function LIBRARY_DEPENDENCY_TO_LIBRARY_MAPPER - = new Function() - { - @Override - public GradleEntityId fun(GradleEntityId id) { - if (id instanceof GradleLibraryDependencyId) { - return ((GradleLibraryDependencyId)id).getLibraryId(); - } - return id; - } - }; - + /** *
    *     ...
@@ -119,14 +113,16 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
         final Runnable task = new Runnable() {
           @Override
           public void run() {
-            Collection c = ContainerUtil.subtract(oldChanges, currentChanges);
+            List currentChangesToUse = ContainerUtilRt.newArrayList(currentChanges);
+            Collection obsoleteChangesToUse = ContainerUtil.subtract(oldChanges, currentChanges);
             if (myChangesComparator != null) {
-              List toSort = new ArrayList(c);
+              List toSort = ContainerUtilRt.newArrayList(obsoleteChangesToUse);
               Collections.sort(toSort, myChangesComparator);
-              c = toSort;
+              obsoleteChangesToUse = toSort;
+              Collections.sort(currentChangesToUse, myChangesComparator);
             }
-            processObsoleteChanges(c);
-            processCurrentChanges(currentChanges);
+            processObsoleteChanges(obsoleteChangesToUse);
+            processCurrentChanges(currentChangesToUse);
           }
         };
         if (myProcessChangesAtTheSameThread) {
@@ -157,7 +153,8 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
     GradleProjectStructureNode root = buildNode(projectId, getProject().getName());
     setRoot(root);
     final Collection modules = myPlatformFacade.getModules(getProject());
-    final List> dependencies = new ArrayList>();
+    final List> dependencies = ContainerUtilRt.newArrayList();
+    final List, Library>> libraryDependencies = ContainerUtilRt.newArrayList();
     RootPolicy visitor = new RootPolicy() {
       @Override
       public Object visitModuleOrderEntry(ModuleOrderEntry moduleOrderEntry, Object value) {
@@ -172,12 +169,15 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
           return value;
         }
         GradleLibraryDependencyId id = GradleEntityIdMapper.mapEntityToId(libraryOrderEntry);
-        dependencies.add(buildNode(id, id.getDependencyName()));
+        GradleProjectStructureNode dependencyNode = buildNode(id, id.getDependencyName());
+        libraryDependencies.add(Pair.create(dependencyNode, libraryOrderEntry.getLibrary()));
+        dependencies.add(dependencyNode);
         return value;
       }
     };
     for (Module module : modules) {
       dependencies.clear();
+      libraryDependencies.clear();
       final GradleModuleId moduleId = GradleEntityIdMapper.mapEntityToId(module);
       final GradleProjectStructureNode moduleNode = buildNode(moduleId, moduleId.getModuleName());
       myModules.put(module.getName(), moduleNode); // Assuming that module names are unique.
@@ -201,11 +201,34 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
       for (GradleProjectStructureNode dependency : dependencies) {
         dependenciesNode.add(dependency);
       }
+      
+      // The general idea is to add jar nodes when all tree nodes above have already been initialized.
+      if (!libraryDependencies.isEmpty()) {
+        for (Pair, Library> p : libraryDependencies) {
+          populateLibraryDependencyNode(p.first, p.second);
+        }
+      }
     }
     processCurrentChanges(myChangesModel.getChanges());
     filterNodes(root);
   }
 
+  private void populateLibraryDependencyNode(@NotNull GradleProjectStructureNode node,
+                                             @Nullable Library library)
+  {
+    if (library == null) {
+      return;
+    }
+
+    GradleLibraryId libraryId = node.getDescriptor().getElement().getLibraryId();
+    for (VirtualFile file : library.getFiles(OrderRootType.CLASSES)) {
+      GradleJarId jarId = new GradleJarId(GradleUtil.getLocalFileSystemPath(file), libraryId);
+      GradleProjectStructureNode jarNode = buildNode(jarId, GradleUtil.extractNameFromPath(jarId.getPath()));
+      jarNode.getDescriptor().setToolTip(jarId.getPath());
+      node.add(jarNode);
+    }
+  }
+
   @TestOnly
   public void setProcessChangesAtTheSameThread(boolean processChangesAtTheSameThread) {
     myProcessChangesAtTheSameThread = processChangesAtTheSameThread;
@@ -436,10 +459,6 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
     getRoot().addConflictChange(change);
   }
 
-  private void processNewMismatchedLibraryPathChange(@NotNull GradleMismatchedLibraryPathChange change) {
-    processDependencyConflictChange(change, LIBRARY_DEPENDENCY_TO_LIBRARY_MAPPER, false);
-  }
-
   private void processNewDependencyScopeChange(@NotNull GradleDependencyScopeChange change) {
     processDependencyConflictChange(change, SELF_MAPPER, false);
   }
@@ -449,14 +468,88 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
   }
   
   private void processNewLibraryDependencyPresenceChange(@NotNull GradleLibraryDependencyPresenceChange change) {
-    processNewDependencyPresenceChange(change);
+    GradleProjectStructureNode dependencyNode = processNewDependencyPresenceChange(change);
+    GradleLibraryDependencyId id = change.getGradleEntity();
+    if (dependencyNode != null && id != null) {
+      GradleLibrary library = myProjectStructureHelper.findGradleLibrary(id.getLibraryId());
+      if (library != null) {
+        GradleLibraryId libraryId = dependencyNode.getDescriptor().getElement().getLibraryId();
+        for (String path : library.getPaths(LibraryPathType.BINARY)) {
+          GradleJarId jarId = new GradleJarId(path, libraryId);
+          GradleProjectStructureNode jarNode = buildNode(jarId, GradleUtil.extractNameFromPath(jarId.getPath()));
+          jarNode.setAttributes(GradleTextAttributes.GRADLE_LOCAL_CHANGE);
+          jarNode.getDescriptor().setToolTip(jarId.getPath());
+          dependencyNode.add(jarNode);
+        }
+      }
+    }
   }
 
+  private void processJarPresenceChange(@NotNull GradleJarPresenceChange change, boolean obsolete) {
+    GradleJarId jarId = change.getGradleEntity();
+    TextAttributesKey attributes = GradleTextAttributes.GRADLE_LOCAL_CHANGE;
+    if (jarId == null) {
+      jarId = change.getIntellijEntity();
+      attributes = GradleTextAttributes.INTELLIJ_LOCAL_CHANGE;
+      assert jarId != null;
+    }
+    if (obsolete) {
+      attributes = GradleTextAttributes.NO_CHANGE;
+    }
+
+    for (Map.Entry> entry : myModuleDependencies.entrySet()) {
+      Collection> libraryDependencies
+        = entry.getValue().getChildren(GradleLibraryDependencyId.class);
+
+      insideModule:
+      for (GradleProjectStructureNode libraryDependencyNode : libraryDependencies) {
+        if (!libraryDependencyNode.getDescriptor().getElement().getLibraryId().equals(jarId.getLibraryId())) {
+          continue;
+        }
+
+        for (GradleProjectStructureNode jarNode : libraryDependencyNode.getChildren(GradleJarId.class)) {
+          if (jarNode.getDescriptor().getElement().equals(jarId)) {
+            if (obsolete && myProjectStructureHelper.findIntellijJar(jarId) == null) {
+              // It was a gradle-local change which is now obsolete. Remove the jar node then.
+              jarNode.removeFromParent();
+            }
+            else {
+              jarNode.setAttributes(attributes);
+            }
+            break insideModule;
+          }
+        }
+
+        if (obsolete) {
+          continue;
+        }
+
+        // There is a possible case that both gradle and intellij have a library with the same name but different jar sets.
+        // We don't want to show intellij-local jars for the gradle-local module which uses that library then.
+        if (jarId.getOwner() ==  GradleEntityOwner.INTELLIJ
+            && myModules.get(entry.getKey()).getDescriptor().getAttributes() == GradleTextAttributes.GRADLE_LOCAL_CHANGE)
+        {
+          continue;
+        }
+
+          // When control flow reaches this place that means that this is a new jar attached to a library. Hence, we need to add a node.
+        GradleProjectStructureNode newNode = buildNode(jarId, GradleUtil.extractNameFromPath(jarId.getPath()));
+        newNode.setAttributes(attributes);
+        newNode.getDescriptor().setToolTip(jarId.getPath());
+        if (passFilters(newNode)) {
+          libraryDependencyNode.add(newNode);
+        }
+      }
+    }
+  }
+  
   private void processNewModuleDependencyPresenceChange(@NotNull GradleModuleDependencyPresenceChange change) {
     processNewDependencyPresenceChange(change);
   }
   
-  private  void processNewDependencyPresenceChange(
+  @SuppressWarnings("unchecked")
+  @Nullable
+  private  GradleProjectStructureNode processNewDependencyPresenceChange(
     @NotNull GradleAbstractEntityPresenceChange change)
   {
     I id = change.getGradleEntity();
@@ -467,21 +560,25 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
     }
     assert id != null;
     final GradleProjectStructureNode dependenciesNode = getDependenciesNode(id.getOwnerModuleId());
-    for (GradleProjectStructureNode node : dependenciesNode.getChildren(id.getClass())) {
+    Class clazz = (Class)id.getClass();
+    for (GradleProjectStructureNode node : dependenciesNode.getChildren(clazz)) {
       if (id.equals(node.getDescriptor().getElement())) {
         node.setAttributes(attributes);
-        return;
+        return node;
       }
     }
     GradleProjectStructureNode newNode = buildNode(id, id.getDependencyName());
     dependenciesNode.add(newNode);
     newNode.setAttributes(attributes);
 
-    if (!passFilters(newNode)) {
-      newNode.removeFromParent();
-      removeModuleDependencyNodeIfEmpty(dependenciesNode, id.getOwnerModuleId());
-      removeModuleNodeIfEmpty(getModuleNode(id.getOwnerModuleId()));
+    if (passFilters(newNode)) {
+      return newNode;
     }
+
+    newNode.removeFromParent();
+    removeModuleDependencyNodeIfEmpty(dependenciesNode, id.getOwnerModuleId());
+    removeModuleNodeIfEmpty(getModuleNode(id.getOwnerModuleId()));
+    return null;
   }
 
   private void processNewModulePresenceChange(@NotNull GradleModulePresenceChange change) {
@@ -537,10 +634,6 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
     getRoot().removeConflictChange(change);
   }
   
-  private void processObsoleteMismatchedLibraryPathChange(@NotNull GradleMismatchedLibraryPathChange change) {
-    processDependencyConflictChange(change, LIBRARY_DEPENDENCY_TO_LIBRARY_MAPPER, true);
-  }
-
   private void processObsoleteDependencyScopeChange(@NotNull GradleDependencyScopeChange change) {
     processDependencyConflictChange(change, SELF_MAPPER, true);
   }
@@ -740,8 +833,8 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
     @Override public void visit(@NotNull GradleModulePresenceChange change) { processNewModulePresenceChange(change); }
     @Override public void visit(@NotNull GradleContentRootPresenceChange change) { processNewContentRootPresenceChange(change); }
     @Override public void visit(@NotNull GradleLibraryDependencyPresenceChange change) { processNewLibraryDependencyPresenceChange(change); }
+    @Override public void visit(@NotNull GradleJarPresenceChange change) { processJarPresenceChange(change, false); }
     @Override public void visit(@NotNull GradleModuleDependencyPresenceChange change) { processNewModuleDependencyPresenceChange(change); }
-    @Override public void visit(@NotNull GradleMismatchedLibraryPathChange change) { processNewMismatchedLibraryPathChange(change); }
     @Override public void visit(@NotNull GradleDependencyScopeChange change) { processNewDependencyScopeChange(change); }
     @Override public void visit(@NotNull GradleDependencyExportedChange change) { processNewDependencyExportedChange(change);
     }
@@ -755,10 +848,10 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
     @Override public void visit(@NotNull GradleLibraryDependencyPresenceChange change) {
       processObsoleteLibraryDependencyPresenceChange(change); 
     }
+    @Override public void visit(@NotNull GradleJarPresenceChange change) { processJarPresenceChange(change, true); }
     @Override public void visit(@NotNull GradleModuleDependencyPresenceChange change) {
       processObsoleteModuleDependencyPresenceChange(change); 
     }
-    @Override public void visit(@NotNull GradleMismatchedLibraryPathChange change) { processObsoleteMismatchedLibraryPathChange(change); }
     @Override public void visit(@NotNull GradleDependencyScopeChange change) { processObsoleteDependencyScopeChange(change); }
     @Override public void visit(@NotNull GradleDependencyExportedChange change) { processObsoleteDependencyExportedChange(change); }
   }
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/conflict/GradleConflictControlFactory.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/conflict/GradleConflictControlFactory.java
index 9399f0eeca0c..c456da679920 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/conflict/GradleConflictControlFactory.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/conflict/GradleConflictControlFactory.java
@@ -32,14 +32,11 @@ import java.util.Collection;
 public class GradleConflictControlFactory {
 
   @NotNull private final GradleProjectConflictControlFactory           myProjectFactory;
-  @NotNull private final GradleLibraryDependencyConflictControlFactory myLibraryDependencyFactory;
   @NotNull private final GradleCommonDependencyConflictControlFactory  myCommonDependencyFactory;
 
   public GradleConflictControlFactory(@NotNull GradleProjectConflictControlFactory factory,
-                                      @NotNull GradleLibraryDependencyConflictControlFactory libraryFactory,
                                       @NotNull GradleCommonDependencyConflictControlFactory commonDependencyFactory) {
     myProjectFactory = factory;
-    myLibraryDependencyFactory = libraryFactory;
     myCommonDependencyFactory = commonDependencyFactory;
   }
 
@@ -70,7 +67,6 @@ public class GradleConflictControlFactory {
 
       @Override
       public void visit(@NotNull LibraryOrderEntry libraryDependency) {
-        result.set(myLibraryDependencyFactory.getControl(libraryDependency, changes));
       }
 
       @Override
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/conflict/GradleLibraryDependencyConflictControlFactory.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/conflict/GradleLibraryDependencyConflictControlFactory.java
deleted file mode 100644
index 9d3fbabc198f..000000000000
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/conflict/GradleLibraryDependencyConflictControlFactory.java
+++ /dev/null
@@ -1,134 +0,0 @@
-package org.jetbrains.plugins.gradle.sync.conflict;
-
-import com.intellij.icons.AllIcons;
-import com.intellij.openapi.roots.LibraryOrderEntry;
-import com.intellij.openapi.roots.OrderRootType;
-import com.intellij.openapi.roots.libraries.Library;
-import com.intellij.openapi.util.Ref;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.ui.SeparatorFactory;
-import com.intellij.ui.treeStructure.Tree;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.gradle.config.GradleTextAttributes;
-import org.jetbrains.plugins.gradle.diff.GradleProjectStructureChange;
-import org.jetbrains.plugins.gradle.diff.GradleProjectStructureChangeVisitor;
-import org.jetbrains.plugins.gradle.diff.GradleProjectStructureChangeVisitorAdapter;
-import org.jetbrains.plugins.gradle.diff.library.GradleMismatchedLibraryPathChange;
-import org.jetbrains.plugins.gradle.model.id.GradleSyntheticId;
-import org.jetbrains.plugins.gradle.ui.GradleProjectStructureNode;
-import org.jetbrains.plugins.gradle.util.GradleBundle;
-import org.jetbrains.plugins.gradle.util.GradleUtil;
-
-import javax.swing.*;
-import javax.swing.tree.DefaultTreeModel;
-import java.awt.*;
-import java.util.Collection;
-import java.util.Set;
-
-/**
- * Provides UI control for representing library setup conflicts.
- * 

- * Thread-safe. - * - * @author Denis Zhdanov - * @since 3/2/12 4:12 PM - */ -public class GradleLibraryDependencyConflictControlFactory { - - @NotNull private final GradleCommonDependencyConflictControlFactory myCommonPropertiesFactory; - - public GradleLibraryDependencyConflictControlFactory(@NotNull GradleCommonDependencyConflictControlFactory factory) { - myCommonPropertiesFactory = factory; - } - - @SuppressWarnings("MethodMayBeStatic") - @Nullable - public JComponent getControl(@NotNull LibraryOrderEntry libraryDependency, Collection changes) { - final Ref pathChangeRef = new Ref(); - GradleProjectStructureChangeVisitor visitor = new GradleProjectStructureChangeVisitorAdapter() { - @Override - public void visit(@NotNull GradleMismatchedLibraryPathChange change) { - pathChangeRef.set(change); - } - }; - for (GradleProjectStructureChange change : changes) { - if (!pathChangeRef.isNull()) { - break; - } - change.invite(visitor); - } - - JComponent commonChangesControl = myCommonPropertiesFactory.getControl(libraryDependency, changes); - final GradleMismatchedLibraryPathChange pathChange = pathChangeRef.get(); - if (commonChangesControl == null && pathChange == null) { - return null; - } - - if (pathChange == null) { - return commonChangesControl; - } - - final Library library = libraryDependency.getLibrary(); - if (library == null) { - return commonChangesControl; - } - - final JComponent pathConflictControl = getPathConflictControl(library, pathChange); - if (commonChangesControl == null) { - return pathConflictControl; - } - - JPanel result = new JPanel(new GridBagLayout()); - GridBagConstraints constraints = new GridBagConstraints(); - constraints.weightx = 1; - constraints.fill = GridBagConstraints.HORIZONTAL; - constraints.anchor = GridBagConstraints.NORTHWEST; - constraints.gridwidth = GridBagConstraints.REMAINDER; - final JComponent commonSeparator = - SeparatorFactory.createSeparator(GradleBundle.message("gradle.sync.change.dependency.common.title"), commonChangesControl); - commonSeparator.setBackground(pathConflictControl.getBackground()); - result.add(commonSeparator, constraints); - result.add(commonChangesControl, constraints); - final JComponent pathSeparator = - SeparatorFactory.createSeparator(GradleBundle.message("gradle.sync.change.library.path.title"), pathConflictControl); - pathSeparator.setBackground(pathConflictControl.getBackground()); - result.add(pathSeparator, constraints); - result.add(pathConflictControl, constraints); - - return result; - } - - private static JComponent getPathConflictControl(@NotNull Library library, @NotNull GradleMismatchedLibraryPathChange pathChange) { - GradleProjectStructureNode root = new GradleProjectStructureNode( - GradleUtil.buildSyntheticDescriptor(GradleUtil.getLibraryName(library), AllIcons.Nodes.PpLib) - ); - for (String path : pathChange.getGradleValue()) { - final GradleProjectStructureNode node = buildPathNode(path); - node.setAttributes(GradleTextAttributes.GRADLE_LOCAL_CHANGE); - root.add(node); - } - - final Set intellijLocalBinaries = pathChange.getIntellijValue(); - for (VirtualFile libRoot : library.getFiles(OrderRootType.CLASSES)) { - final String path = GradleUtil.getLocalFileSystemPath(libRoot); - GradleProjectStructureNode node = buildPathNode(path); - if (intellijLocalBinaries.contains(path)) { - node.setAttributes(GradleTextAttributes.INTELLIJ_LOCAL_CHANGE); - } - root.add(node); - } - - DefaultTreeModel model = new DefaultTreeModel(root); - return new Tree(model); - } - - private static GradleProjectStructureNode buildPathNode(@NotNull String path) { - final int i = path.lastIndexOf('/'); - final String name = i < 0 || i >= path.length() - 1 ? path : path.substring(i + 1); - final GradleProjectStructureNode result - = new GradleProjectStructureNode(GradleUtil.buildSyntheticDescriptor(name, AllIcons.Nodes.PpJar)); - result.getDescriptor().setToolTip(path); - return result; - } -} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleProjectStructureNodeComparator.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleProjectStructureNodeComparator.java index 6195128e5cc9..1506cad2184e 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleProjectStructureNodeComparator.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleProjectStructureNodeComparator.java @@ -30,15 +30,16 @@ import java.util.Comparator; */ public class GradleProjectStructureNodeComparator implements Comparator> { - private static final int PROJECT_WEIGHT = 0; + private static final int PROJECT_WEIGHT = 0; private static final int MODULE_WEIGHT = 1; private static final int CONTENT_ROOT_WEIGHT = 2; private static final int SYNTHETIC_WEIGHT = 3; private static final int MODULE_DEPENDENCY_WEIGHT = 4; private static final int LIBRARY_DEPENDENCY_WEIGHT = 5; private static final int LIBRARY_WEIGHT = 6; + private static final int JAR_WEIGHT = 7; private static final int UNKNOWN_WEIGHT = 20; - + @NotNull private final GradleProjectStructureContext myContext; public GradleProjectStructureNodeComparator(@NotNull GradleProjectStructureContext context) { @@ -100,6 +101,11 @@ public class GradleProjectStructureNodeComparator implements Comparator exte public void setToolTip(@NotNull String text) { getTemplatePresentation().setTooltip(text); + update(); } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java index 89784d7e691d..e2d5dec5e8e3 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java @@ -406,22 +406,9 @@ public class GradleUtil { if (result != null) { return result; } - String[] endingsToStrip = { "/", "!", ".jar" }; - StringBuilder buffer = new StringBuilder(); for (OrderRootType type : OrderRootType.getAllTypes()) { for (String url : library.getUrls(type)) { - buffer.setLength(0); - buffer.append(url); - for (String ending : endingsToStrip) { - if (buffer.lastIndexOf(ending) == buffer.length() - ending.length()) { - buffer.setLength(buffer.length() - ending.length()); - } - } - final int i = buffer.lastIndexOf(PATH_SEPARATOR); - if (i < 0 || i >= buffer.length() - 1) { - continue; - } - String candidate = buffer.substring(i + 1); + String candidate = extractNameFromPath(url); if (!StringUtil.isEmpty(candidate)) { return candidate; } @@ -431,6 +418,32 @@ public class GradleUtil { return "unknown-lib"; } + @NotNull + public static String extractNameFromPath(@NotNull String path) { + String strippedPath = stripPath(path); + final int i = strippedPath.lastIndexOf(PATH_SEPARATOR); + final String result; + if (i < 0 || i >= strippedPath.length() - 1) { + result = strippedPath; + } + else { + result = strippedPath.substring(i + 1); + } + return result; + } + + @NotNull + private static String stripPath(@NotNull String path) { + String[] endingsToStrip = { "/", "!", ".jar" }; + StringBuilder buffer = new StringBuilder(path); + for (String ending : endingsToStrip) { + if (buffer.lastIndexOf(ending) == buffer.length() - ending.length()) { + buffer.setLength(buffer.length() - ending.length()); + } + } + return buffer.toString(); + } + /** * Tries to find the current {@link GradleProjectStructureTreeModel} instance. * diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/manage/GradleLocalNodeManageHelperTest.groovy b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/manage/GradleLocalNodeManageHelperTest.groovy index cfa25f16b6d0..cc436dad1d4c 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/manage/GradleLocalNodeManageHelperTest.groovy +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/manage/GradleLocalNodeManageHelperTest.groovy @@ -23,6 +23,7 @@ public class GradleLocalNodeManageHelperTest extends AbstractGradleTest { container.registerComponentImplementation(GradleLocalNodeManageHelper) container.registerComponentImplementation(GradleModuleManager) container.registerComponentImplementation(GradleLibraryManager) + container.registerComponentImplementation(GradleJarManager) container.registerComponentImplementation(GradleDependencyManager) container.registerComponentImplementation(GradleContentRootManager) } @@ -49,7 +50,8 @@ public class GradleLocalNodeManageHelperTest extends AbstractGradleTest { contentRoot('1', transitive: true, order: 1) } } } } - + + @SuppressWarnings("GroovyAssignabilityCheck") private def doTest(Closure c) { myHelper = container.getComponentInstance(GradleLocalNodeManageHelper) def compositeBuilder = new CompositeProjectBuilder(gradleBuilder: gradle, intellijBuilder: intellij) diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesModelTest.groovy b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesModelTest.groovy index 409da42bf372..7f1c41cd086c 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesModelTest.groovy +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesModelTest.groovy @@ -2,11 +2,12 @@ package org.jetbrains.plugins.gradle.sync; import com.intellij.testFramework.SkipInHeadlessEnvironment +import org.jetbrains.plugins.gradle.diff.library.GradleJarPresenceChange +import org.jetbrains.plugins.gradle.diff.module.GradleModulePresenceChange import org.jetbrains.plugins.gradle.testutil.AbstractGradleTest import org.junit.Test import static org.junit.Assert.assertEquals -import org.jetbrains.plugins.gradle.diff.library.GradleMismatchedLibraryPathChange import org.jetbrains.plugins.gradle.diff.dependency.GradleLibraryDependencyPresenceChange import org.jetbrains.plugins.gradle.config.GradleTextAttributes @@ -107,28 +108,30 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest { module { dependencies { library("lib1") - library("lib2", bin: ['1', '2']) - } } } }, + library("lib2", bin: ['jar1', 'jar2']) } } } }, intellij: { project { module { dependencies { library("lib1") - library("lib2", bin: ['2', '3']) - } } } } - ) + library("lib2", bin: ['jar2', 'jar3']) } } } }) checkChanges { - libraryConflict(entity: intellij.libraries['lib2']) { - binaryPath(gradle: '1', intellij: ['3']) - } } + presence { + jar(gradle: [findJarId('jar1')]) + jar(intellij: [findJarId('jar3')]) + } + } + checkTree { project { module { dependencies { lib1() - lib2('conflict') - } } } } + lib2 { + jar1('gradle') + jar2() + jar3('intellij') } } } } } // Remove one difference from the library setup and check that the corresponding node is still marked as conflicted setState( @@ -137,27 +140,28 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest { module { dependencies { library("lib1") - library("lib2", bin: ['2']) - } } } }, + library("lib2", bin: ['jar2']) } } } }, intellij: { project { module { dependencies { library("lib1") - library("lib2", bin: ['2', '3']) - } } } } - ) + library("lib2", bin: ['jar2', 'jar3']) } } } }) + checkChanges { - libraryConflict(entity: intellij.libraryDependencies.values().flatten().find {it.library.name == 'lib2' }.library) { - binaryPath(gradle: null, intellij: '3') - } } + presence { + jar(intellij: [findJarId('jar3')]) + } + } + checkTree { project { module { dependencies { lib1() - lib2('conflict') - } } } } + lib2 { + jar2() + jar3('intellij') } } } } } // Match the remaining change and check that the corresponding node is not marked as conflicted anymore. setState( @@ -166,24 +170,102 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest { module { dependencies { library("lib1") - library("lib2", bin: ['2', '3']) + library("lib2", bin: ['jar2', 'jar3']) } } } }, intellij: { project { module { dependencies { library("lib1") - library("lib2", bin: ['2', '3']) - } } } } - ) + library("lib2", bin: ['jar2', 'jar3']) } } } }) checkChanges { } // No changes checkTree { project { module { dependencies { lib1() - lib2() - } } } } + lib2 { + jar2() + jar3() } } } } } + } + + @Test + public void "gradle-local module which library setup differs from intellij when jar presence change goes first"() { + init( + gradle: { + project { + module('module1') { + dependencies { + library("lib1", bin: ['jar1', 'jar2']) }} + module('module2') { + dependencies { + library("lib1", bin: ['jar1', 'jar2']) } } } }, + intellij: { + project { + module('module1') { + dependencies { + library("lib1", bin: ['jar2', 'jar3']) } } } }, + changesSorter: changeByClassSorter([ + (GradleJarPresenceChange) : 1, + (GradleLibraryDependencyPresenceChange) : 2, + (GradleModulePresenceChange) : 3, + ]) + ) + + checkChanges { + presence { + jar(gradle: [findJarId('jar1')]) + jar(intellij: [findJarId('jar3')]) + library(gradle: gradle.libraryDependencies[gradle.modules['module2']].find { it.name == "lib1" }) + module(gradle: gradle.modules['module2']) + } + } + + checkTree { + project { + module2('gradle') { + dependencies { + lib1('gradle') { + jar1('gradle') + jar2('gradle')} } } + module1 { + dependencies { + lib1 { + jar1('gradle') + jar2() + jar3('intellij') } } } } } + } + + @Test + public void "adding intellij-local jar"() { + Closure initialProject = { + project { + module { + dependencies { + library('lib1', bin: ['jar1'])} } } } + init(gradle: initialProject, intellij: initialProject) + checkChanges {} // empty + + setState( + intellij: { + project { + module { + dependencies { + library('lib1', bin: ['jar1', 'jar2']) + } } } } + ) + + checkChanges { + presence { + jar(intellij: [findJarId('jar2')]) + } } + checkTree { + project { + module { + dependencies { + lib1 { + jar1() + jar2('intellij')} } } } } } @Test @@ -271,42 +353,42 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest { project { module('module1') { dependencies { - library('lib1', bin: ['1']) - } } + library('lib1', bin: ['jar1']) } } module('module2') { dependencies { - library('lib1') - } } } }, + library('lib1') } } } }, intellij: { project { module('module1') { dependencies { - library('lib1', bin: ['2']) - } } } }, + library('lib1', bin: ['jar2']) } } } }, changesSorter: changeByClassSorter([ - (GradleMismatchedLibraryPathChange) : 2, - (GradleLibraryDependencyPresenceChange) : 1 + (GradleModulePresenceChange) : 1, + (GradleLibraryDependencyPresenceChange) : 2, + (GradleJarPresenceChange) : 3, ]) ) checkChanges { presence { module(gradle: gradle.modules['module2']) + jar(gradle: [findJarId('jar1')]) + jar(intellij: [findJarId('jar2')]) libraryDependency(gradle: gradle.libraryDependencies[gradle.modules['module2']].first()) } - libraryConflict(entity: intellij.libraries['lib1']) { - binaryPath(gradle: ['1'], intellij: ['2']) - } } + } + checkTree { project { module2('gradle') { dependencies { - lib1('gradle') // This is the point of the test. We don't expect to see 'conflict' here. - } } + lib1('gradle') { + jar1('gradle') } } } module1() { dependencies { - lib1('conflict') - } } } } + lib1 { + jar1('gradle') + jar2('intellij') } } } } } } @Test @@ -486,73 +568,6 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest { } } } } } - @Test - public void "mismatched library path is highlighted after importing local library dependency"() { - init( - gradle: { - project { - module('module1') { - dependencies { - library('lib1', bin: ['1']) - } } - module('module2') { - dependencies { - library('lib1') - } } } }, - intellij: { - project { - module('module1') { - dependencies { - library('lib1', bin: ['2']) - } } } } - ) - checkChanges { - presence { - module(gradle: gradle.modules['module2']) - libraryDependency(gradle: gradle.libraryDependencies[gradle.modules['module2']]) - } - libraryConflict(entity: intellij.libraries['lib1']) { - binaryPath(gradle: '1', intellij: ['2']) - } } - checkTree { - project { - module2('gradle') { - dependencies { - lib1('gradle') - } } - module1 { - dependencies { - lib1('conflict') - } } } } - - // Emulate importing missing module and library dependencies. Expecting to see the newly imported library dependency node - // highlighted as 'conflict' now. - setState(intellij: { - project { - module('module1') { - dependencies { - library('lib1', bin: ['2']) - } } - module('module2') { - dependencies { - library('lib1') - } } } }) - checkChanges { - libraryConflict(entity: intellij.libraries['lib1']) { - binaryPath(gradle: '1', intellij: ['2']) - } } - checkTree { - project { - module1 { - dependencies { - lib1('conflict') - } } - module2() { - dependencies { - lib1('conflict') - } } } } - } - @Test public void "local content root importing"() { init( @@ -791,7 +806,6 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest { project { module2 { dependencies { - lib1('conflict') module1('conflict') } } } } diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/AbstractGradleTest.groovy b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/AbstractGradleTest.groovy index 88d78d05feba..d21c03409ad4 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/AbstractGradleTest.groovy +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/AbstractGradleTest.groovy @@ -2,6 +2,9 @@ package org.jetbrains.plugins.gradle.testutil import com.intellij.openapi.editor.colors.TextAttributesKey import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.OrderRootType +import com.intellij.openapi.roots.libraries.Library +import org.jetbrains.annotations.NotNull import org.jetbrains.plugins.gradle.action.AbstractGradleSyncTreeFilterAction import org.jetbrains.plugins.gradle.config.GradleColorAndFontDescriptorsProvider import org.jetbrains.plugins.gradle.config.PlatformFacade @@ -12,12 +15,18 @@ 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.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.GradleProjectStructureChangesModel import org.jetbrains.plugins.gradle.sync.GradleProjectStructureHelper import org.jetbrains.plugins.gradle.sync.GradleProjectStructureTreeModel import org.jetbrains.plugins.gradle.ui.GradleProjectStructureNodeFilter import org.jetbrains.plugins.gradle.util.GradleProjectStructureContext +import org.jetbrains.plugins.gradle.util.GradleUtil import org.junit.Before import org.picocontainer.MutablePicoContainer import org.picocontainer.defaults.DefaultPicoContainer @@ -32,10 +41,10 @@ public abstract class AbstractGradleTest { GradleProjectStructureChangesModel changesModel GradleProjectStructureTreeModel treeModel - def gradle - def intellij + GradleProjectBuilder gradle + IntellijProjectBuilder intellij def changesBuilder - def treeChecker + ProjectStructureChecker treeChecker def container private Map treeFilters = [:] @@ -123,7 +132,7 @@ public abstract class AbstractGradleTest { treeChecker.check(expected, treeModel.root) } - protected Closure changeByClassSorter(Map, Integer> rules) { + protected static Closure changeByClassSorter(Map, Integer> rules) { { a, b -> def weightA = rules[a.class] ?: Integer.MAX_VALUE def weightB = rules[b.class] ?: Integer.MAX_VALUE @@ -139,4 +148,35 @@ public abstract class AbstractGradleTest { protected def applyTreeFilter(TextAttributesKey toShow) { treeModel.addFilter(treeFilters[toShow]) } + + @NotNull + protected GradleJarId findJarId(@NotNull String path) { + String pathToUse = GradleUtil.toCanonicalPath(path) + for (GradleLibrary library in (gradle.libraries.values() as Collection)) { + for (libPath in library.getPaths(LibraryPathType.BINARY)) { + if (libPath == pathToUse) { + return new GradleJarId(pathToUse, new GradleLibraryId(GradleEntityOwner.GRADLE, library.name)) + } + } + } + + for (Library library in (intellij.libraries.values() as Collection)) { + for (jarFile in library.getFiles(OrderRootType.CLASSES)) { + if (pathToUse == jarFile.path) { + return new GradleJarId(pathToUse, new GradleLibraryId(GradleEntityOwner.INTELLIJ, library.name)) + } + } + } + + String errorMessage = """ +Can't build an id object for given jar path ($path). + Available gradle libraries: + ${gradle.libraries.values().collect { GradleLibrary lib -> "${lib.name}: ${lib.getPaths(LibraryPathType.BINARY)}" }.join('\n ') } + Available intellij libraries: + ${intellij.libraries.values().collect { Library lib -> "${lib.name}: ${lib.getFiles(OrderRootType.CLASSES).collect{it.path}}" } + .join('\n ')} +""" + + throw new IllegalArgumentException(errorMessage) + } } diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/ChangeBuilder.groovy b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/ChangeBuilder.groovy index 5fa3f030b98c..b5e7d56ae520 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/ChangeBuilder.groovy +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/ChangeBuilder.groovy @@ -1,13 +1,10 @@ -package org.jetbrains.plugins.gradle.testutil; +package org.jetbrains.plugins.gradle.testutil - -import org.jetbrains.plugins.gradle.diff.dependency.GradleLibraryDependencyPresenceChange -import org.jetbrains.plugins.gradle.diff.library.GradleMismatchedLibraryPathChange -import com.intellij.openapi.roots.libraries.Library -import org.jetbrains.plugins.gradle.util.GradleUtil -import org.jetbrains.plugins.gradle.diff.module.GradleModulePresenceChange -import org.jetbrains.plugins.gradle.diff.dependency.GradleModuleDependencyPresenceChange import org.jetbrains.plugins.gradle.diff.contentroot.GradleContentRootPresenceChange +import org.jetbrains.plugins.gradle.diff.dependency.GradleLibraryDependencyPresenceChange +import org.jetbrains.plugins.gradle.diff.dependency.GradleModuleDependencyPresenceChange +import org.jetbrains.plugins.gradle.diff.library.GradleJarPresenceChange +import org.jetbrains.plugins.gradle.diff.module.GradleModulePresenceChange /** * @author Denis Zhdanov @@ -58,11 +55,9 @@ public class ChangeBuilder extends BuilderSupport { changes.addAll attributes.gradle.collect { new GradleContentRootPresenceChange(it, null)} changes.addAll attributes.intellij.collect { new GradleContentRootPresenceChange(null, it)} return changes - case "binaryPath": - // Assuming that we're processing library binary path conflict here - register(new GradleMismatchedLibraryPathChange( - current as Library, collectPaths(attributes.gradle), collectPaths(attributes.intellij) - )) + case "jar": + changes.addAll attributes.gradle.collect { new GradleJarPresenceChange(it, null) } + changes.addAll attributes.intellij.collect { new GradleJarPresenceChange(null, it) } } changes } @@ -79,15 +74,4 @@ public class ChangeBuilder extends BuilderSupport { changes << change changes } - - private def collectPaths(paths) { - if (!paths) { - return [].toSet() - } - paths.collect { toCanonicalPath(it) }.toSet() - } - - private def toCanonicalPath(String path) { - path ? GradleUtil.toCanonicalPath(path) : path - } } diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/GradleProjectBuilder.groovy b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/GradleProjectBuilder.groovy index 9f76b8405800..cb36e50cb22c 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/GradleProjectBuilder.groovy +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/GradleProjectBuilder.groovy @@ -54,6 +54,7 @@ class GradleProjectBuilder extends AbstractProjectBuilder { protected createLibrary(String name, Map paths) { def result = new GradleLibrary(name) applyLibraryPaths(result, paths) + project.addLibrary(result) result } diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/IntellijProjectBuilder.groovy b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/IntellijProjectBuilder.groovy index b5e64a4ff370..7c405f01baf5 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/IntellijProjectBuilder.groovy +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/IntellijProjectBuilder.groovy @@ -1,5 +1,6 @@ package org.jetbrains.plugins.gradle.testutil +import com.intellij.openapi.fileTypes.FileTypes import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ContentEntry @@ -107,7 +108,10 @@ class IntellijProjectBuilder extends AbstractProjectBuilder { @Override protected reset() { } - private def asVirtualFile(path) { - [getPath: { GradleUtil.toCanonicalPath(path) }] as VirtualFile + private static def asVirtualFile(path) { + [ + getPath: { GradleUtil.toCanonicalPath(path) }, + getFileType: { FileTypes.UNKNOWN } + ] as VirtualFile } } diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/ProjectStructureChecker.groovy b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/ProjectStructureChecker.groovy index e55b7a25943b..88df5c10ef4d 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/ProjectStructureChecker.groovy +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/ProjectStructureChecker.groovy @@ -2,6 +2,10 @@ package org.jetbrains.plugins.gradle.testutil import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project +import org.jetbrains.annotations.NotNull +import org.jetbrains.plugins.gradle.model.id.GradleEntityId +import org.jetbrains.plugins.gradle.ui.GradleProjectStructureNode + import javax.swing.tree.DefaultMutableTreeNode import org.jetbrains.plugins.gradle.config.GradleTextAttributes import org.jetbrains.plugins.gradle.ui.GradleProjectStructureNodeDescriptor @@ -44,15 +48,26 @@ class ProjectStructureChecker { check it as Node, actual.getChildAt(childIndex++) as DefaultMutableTreeNode } if (childIndex < actual.childCount) { - fail("Unexpected nodes detected: ${(childIndex..) } + fail("Unexpected nodes detected: ${(childIndex.. node) { + StringBuilder result = new StringBuilder("'${node.descriptor.name}") + for (GradleProjectStructureNode n = node.parent; n != null; n = n.parent) { + result.append(" -> ${n.descriptor.name}") + } + result.append("'") + result.toString() + } + + private static void checkName(Node expected, GradleProjectStructureNodeDescriptor actual) { if (AbstractProjectBuilder.SAME_TOKEN == actual.toString() || expected.name() == actual.toString()) { return } - def clazz = BUILT_IN[expected.name()] + def clazz = BUILT_IN[expected.name().toString()] if (clazz == null || !clazz.isAssignableFrom(actual.element.class)) { Assert.fail( "Failed node name check. Expected to find name '${expected.name()}'" + (clazz ? " or user object of type ${clazz.simpleName}" : "") @@ -61,8 +76,8 @@ class ProjectStructureChecker { } } - def checkMarkup(Node node, GradleProjectStructureNodeDescriptor descriptor) { - def expectedMarkup = COLORS[node.children().find {it instanceof CharSequence}]?: GradleTextAttributes.NO_CHANGE + static def checkMarkup(Node node, GradleProjectStructureNodeDescriptor descriptor) { + def expectedMarkup = COLORS[node.children().find {it instanceof CharSequence}.toString()]?: GradleTextAttributes.NO_CHANGE assertEquals("node '$descriptor'", expectedMarkup, descriptor.attributes) if (descriptor.element.type != GradleEntityType.SYNTHETIC) { diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/util/RichTextControlBuilderTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/util/RichTextControlBuilderTest.java index a140c55fc217..ed52a1b4c458 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/util/RichTextControlBuilderTest.java +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/util/RichTextControlBuilderTest.java @@ -12,6 +12,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import javax.swing.*; + /** * @author Denis Zhdanov * @since 01/17/2012 @@ -59,8 +61,8 @@ public class RichTextControlBuilderTest { public void completeMetaInfo() { String text = String.format("this is a test text with two inline meta-datas: {@%s meta \t text} and {@%s}", META_KEY, META_KEY); myMockery.checking(new Expectations() {{ - one(myProcessor).process("meta \t text"); - one(myProcessor).process(""); + one(myProcessor).process("meta \t text"); will(returnValue(new JLabel(""))); + one(myProcessor).process(""); will(returnValue(new JLabel(""))); }}); myBuilder.setText(text); }