From 4ebed60d95754bb66678634b9e193b0196637ecc Mon Sep 17 00:00:00 2001 From: Alexander Bubenchikov Date: Mon, 23 Dec 2019 16:06:14 +0300 Subject: [PATCH] maven new model import - do not use RootModel GitOrigin-RevId: 1d09ac93b42b2339f5e67ada0795b2c85a65a06c --- .../maven/importing/MavenFoldersImporter.java | 53 ++++--- .../maven/importing/MavenModuleImporter.java | 20 ++- .../maven/importing/MavenProjectImporter.java | 108 +++----------- .../MavenRootModelAdapterLegacyImpl.java | 10 +- .../LegacyBridgeMavenRootModelAdapter.kt | 73 +++++++--- ...LegacyBrigdeIdeModifiableModelsProvider.kt | 15 +- .../worktree/WorkspaceModuleImporter.kt | 136 ++++++++++++++++++ .../maven/project/MavenProjectsManager.java | 3 +- .../jetbrains/idea/maven/utils/MavenUtil.java | 17 ++- .../maven/wizards/MavenProjectBuilder.java | 3 +- .../importing/DependenciesImportingTest.java | 16 +-- 11 files changed, 300 insertions(+), 154 deletions(-) create mode 100644 plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/worktree/WorkspaceModuleImporter.kt diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java index dbed4efa86d4..52962035bf39 100755 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java @@ -105,40 +105,61 @@ public class MavenFoldersImporter { } private void configSourceFolders() { + Map> sourceFolders = getSourceFolders(myMavenProject); + + sourceFolders.forEach((p, t) -> myModel.addSourceFolder(p, t)); + } + + private static boolean alreadyAdded(String canonicalPath, Map addedPaths) { + for (String existing : addedPaths.keySet()) { + if (VfsUtilCore.isEqualOrAncestor(existing, canonicalPath) + || VfsUtilCore.isEqualOrAncestor(canonicalPath, existing)) { + return true; + } + } + return false; + } + + @NotNull + public static Map> getSourceFolders(MavenProject mavenProject) { final MultiMap, String> roots = new LinkedMultiMap<>(); - roots.putValues(JavaSourceRootType.SOURCE, myMavenProject.getSources()); - roots.putValues(JavaSourceRootType.TEST_SOURCE, myMavenProject.getTestSources()); + roots.putValues(JavaSourceRootType.SOURCE, mavenProject.getSources()); + roots.putValues(JavaSourceRootType.TEST_SOURCE, mavenProject.getTestSources()); - for (MavenImporter each : MavenImporter.getSuitableImporters(myMavenProject)) { - each.collectSourceRoots(myMavenProject, (s, type) -> roots.putValue(type, s)); + for (MavenImporter each : MavenImporter.getSuitableImporters(mavenProject)) { + each.collectSourceRoots(mavenProject, (s, type) -> roots.putValue(type, s)); } - for (MavenResource each : myMavenProject.getResources()) { + for (MavenResource each : mavenProject.getResources()) { roots.putValue(JavaResourceRootType.RESOURCE, each.getDirectory()); } - for (MavenResource each : myMavenProject.getTestResources()) { + for (MavenResource each : mavenProject.getTestResources()) { roots.putValue(JavaResourceRootType.TEST_RESOURCE, each.getDirectory()); } - addBuilderHelperPaths("add-source", roots.getModifiable(JavaSourceRootType.SOURCE)); - addBuilderHelperPaths("add-test-source", roots.getModifiable(JavaSourceRootType.TEST_SOURCE)); + addBuilderHelperPaths(mavenProject, "add-source", roots.getModifiable(JavaSourceRootType.SOURCE)); + addBuilderHelperPaths(mavenProject, "add-test-source", roots.getModifiable(JavaSourceRootType.TEST_SOURCE)); - addBuilderHelperResourcesPaths("add-resource", roots.getModifiable(JavaResourceRootType.RESOURCE)); - addBuilderHelperResourcesPaths("add-test-resource", roots.getModifiable(JavaResourceRootType.TEST_RESOURCE)); + addBuilderHelperResourcesPaths(mavenProject, "add-resource", roots.getModifiable(JavaResourceRootType.RESOURCE)); + addBuilderHelperResourcesPaths(mavenProject, "add-test-resource", roots.getModifiable(JavaResourceRootType.TEST_RESOURCE)); - List addedPaths = new ArrayList<>(); + Map> addedPaths = new LinkedHashMap<>(); for (JpsModuleSourceRootType type : roots.keySet()) { for (String path : roots.get(type)) { if (path != null) { - addSourceFolderIfNotOverlap(path, type, addedPaths); + String canonicalPath = MavenUtil.toPath(mavenProject, path).getPath(); + if (!alreadyAdded(canonicalPath, addedPaths)) { + addedPaths.put(canonicalPath, type); + } } } } + return addedPaths; } - private void addBuilderHelperPaths(String goal, Collection folders) { - final MavenPlugin plugin = myMavenProject.findPlugin("org.codehaus.mojo", "build-helper-maven-plugin"); + private static void addBuilderHelperPaths(MavenProject mavenProject, String goal, Collection folders) { + final MavenPlugin plugin = mavenProject.findPlugin("org.codehaus.mojo", "build-helper-maven-plugin"); if (plugin != null) { for (MavenPlugin.Execution execution : plugin.getExecutions()) { if (execution.getGoals().contains(goal)) { @@ -156,8 +177,8 @@ public class MavenFoldersImporter { } } - private void addBuilderHelperResourcesPaths(String goal, Collection folders) { - final MavenPlugin plugin = myMavenProject.findPlugin("org.codehaus.mojo", "build-helper-maven-plugin"); + private static void addBuilderHelperResourcesPaths(MavenProject mavenProject, String goal, Collection folders) { + final MavenPlugin plugin = mavenProject.findPlugin("org.codehaus.mojo", "build-helper-maven-plugin"); if (plugin != null) { for (MavenPlugin.Execution execution : plugin.getExecutions()) { if (execution.getGoals().contains(goal)) { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java index ce3e7b2058d7..644860f50ed6 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java @@ -325,6 +325,7 @@ public class MavenModuleImporter { } } + //TODO: Rewrite private void addAttachArtifactDependency(@NotNull Element buildHelperCfg, @NotNull DependencyScope scope, @NotNull MavenProject mavenProject, @@ -392,18 +393,23 @@ public class MavenModuleImporter { private void configLanguageLevel() { if ("false".equalsIgnoreCase(System.getProperty("idea.maven.configure.language.level"))) return; + LanguageLevel level = getLanguageLevel(myMavenProject); + myRootModelAdapter.setLanguageLevel(level); + } + + public static LanguageLevel getLanguageLevel(MavenProject mavenProject) { LanguageLevel level = null; - Element cfg = myMavenProject.getPluginConfiguration("com.googlecode", "maven-idea-plugin"); + Element cfg = mavenProject.getPluginConfiguration("com.googlecode", "maven-idea-plugin"); if (cfg != null) { level = MAVEN_IDEA_PLUGIN_LEVELS.get(cfg.getChildTextTrim("jdkLevel")); } if (level == null) { - String mavenProjectReleaseLevel = myMavenProject.getReleaseLevel(); + String mavenProjectReleaseLevel = mavenProject.getReleaseLevel(); level = LanguageLevel.parse(mavenProjectReleaseLevel); if (level == null) { - String mavenProjectSourceLevel = myMavenProject.getSourceLevel(); + String mavenProjectSourceLevel = mavenProject.getSourceLevel(); level = LanguageLevel.parse(mavenProjectSourceLevel); if (level == null && (StringUtil.isNotEmpty(mavenProjectSourceLevel) || StringUtil.isNotEmpty(mavenProjectReleaseLevel))) { level = LanguageLevel.HIGHEST; @@ -417,13 +423,13 @@ public class MavenModuleImporter { } if (level.isAtLeast(LanguageLevel.JDK_11)) { - level = adjustPreviewLanguageLevel(level); + level = adjustPreviewLanguageLevel(mavenProject, level); } - myRootModelAdapter.setLanguageLevel(level); + return level; } - private LanguageLevel adjustPreviewLanguageLevel(LanguageLevel level) { - Element compilerConfiguration = myMavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-compiler-plugin"); + private static LanguageLevel adjustPreviewLanguageLevel(MavenProject mavenProject, LanguageLevel level) { + Element compilerConfiguration = mavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-compiler-plugin"); if (compilerConfiguration != null) { Element compilerArgs = compilerConfiguration.getChild("compilerArgs"); if (compilerArgs != null) { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporter.java index 4bd88b6a69dc..f7a1e085dcc5 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporter.java @@ -2,7 +2,6 @@ package org.jetbrains.idea.maven.importing; import com.intellij.compiler.impl.javaCompiler.javac.JavacConfiguration; -import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.diagnostic.Logger; @@ -11,30 +10,35 @@ import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsPr import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.module.ModuleTypeId; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.LibraryOrderEntry; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootModel; +import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.roots.impl.libraries.LibraryImpl; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ArrayUtilRt; import com.intellij.util.containers.Stack; -import com.intellij.workspace.api.*; +import com.intellij.workspace.api.TypedEntity; +import com.intellij.workspace.api.TypedEntityStorage; +import com.intellij.workspace.api.TypedEntityStorageBuilder; import com.intellij.workspace.ide.WorkspaceModel; -import com.intellij.workspace.legacyBridge.intellij.LegacyBridgeModuleManagerComponent; -import com.intellij.workspace.legacyBridge.intellij.LegacyBridgeProjectLifecycleListener; +import com.intellij.workspace.legacyBridge.intellij.LegacyBridgeModule; import gnu.trove.THashMap; import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.maven.importing.configurers.MavenModuleConfigurer; -import org.jetbrains.idea.maven.importing.worktree.LegacyBridgeMavenRootModelAdapter; import org.jetbrains.idea.maven.importing.worktree.LegacyBrigdeIdeModifiableModelsProvider; import org.jetbrains.idea.maven.importing.worktree.MavenExternalSource; +import org.jetbrains.idea.maven.importing.worktree.WorkspaceModuleImporter; import org.jetbrains.idea.maven.model.MavenArtifact; import org.jetbrains.idea.maven.model.MavenId; import org.jetbrains.idea.maven.project.*; @@ -90,7 +94,7 @@ public class MavenProjectImporter { @Nullable public List importProject() { - if (LegacyBridgeProjectLifecycleListener.Companion.enabled(myProject)) { + if (MavenUtil.newModelEnabled(myProject)) { return importProjectAsWorkspaceModel(); } else { @@ -120,88 +124,14 @@ public class MavenProjectImporter { myAllProjects.addAll(projectsToImportWithChanges.keySet()); // some projects may already have been removed from the tree - mapMavenProjectsToModulesAndNames(); - - - if (myProject.isDisposed()) return null; LegacyBrigdeIdeModifiableModelsProvider legacyBridgeModelsProvider = (LegacyBrigdeIdeModifiableModelsProvider)myModelsProvider; TypedEntityStorageBuilder diff = legacyBridgeModelsProvider.getDiff(); - TypedEntityStore store = new EntityStoreOnBuilder(diff); - - Set projectsWithNewlyCreatedModules = new THashSet<>(); - Map moduleEntityMap = new HashMap<>(); - Disposable tempDisposable = Disposer.newDisposable("Tmp modules"); for (MavenProject each : myAllProjects) { - if (myMavenProjectToModule.get(each) != null) continue; - - final String path = myMavenProjectToModulePath.get(each); - deleteExistingImlFile(path); - - ModuleEntity entity = findFirst(diff, ModuleEntity.class, e -> e.getName().equals(each.getDisplayName())); - if (entity == null) { - entity = ModifiableProxyBasedImlModelEntitiesKt - .addModuleEntity(diff, each.getDisplayName(), Collections.emptyList(), MavenExternalSource.getINSTANCE()); - } - Module module = LegacyBridgeModuleManagerComponent.getInstance(myProject).createModuleInstance(entity, store, diff, true); - Disposer.register(tempDisposable, module); - ModuleEntity finalEntity = entity; - ContentRootEntity contentRootEntity = findFirst(diff, ContentRootEntity.class, e -> e.getModule().equals(finalEntity)); - if (contentRootEntity == null) { - ModifiableProxyBasedImlModelEntitiesKt - .addContentRootEntity(diff, VirtualFileUrlManager.INSTANCE.fromUrl(each.getDirectoryFile().getUrl()), Collections.emptyList(), - Collections.emptyList(), entity, MavenExternalSource.getINSTANCE()); - } - myMavenProjectToModule.put(each, module); - myCreatedModules.add(module); - projectsWithNewlyCreatedModules.add(each); - moduleEntityMap.put(each, entity); + new WorkspaceModuleImporter(myProject, each, myProjectsTree, diff).importModule(); } - List modulesToMavenize = new ArrayList<>(); - List importers = new ArrayList<>(); - - for (MavenProject project : myAllProjects) { - Module module = myMavenProjectToModule.get(project); - boolean isNewModule = projectsWithNewlyCreatedModules.contains(project); - MavenId mavenId = project.getMavenId(); - myModelsProvider.registerModulePublication( - module, new ProjectId(mavenId.getGroupId(), mavenId.getArtifactId(), mavenId.getVersion())); - MavenModuleImporter moduleImporter = createModuleImporter(module, project, ALL); - modulesToMavenize.add(module); - importers.add(moduleImporter); - - ModuleEntity entity = moduleEntityMap.get(project); - if (entity == null) { - entity = ModifiableProxyBasedImlModelEntitiesKt - .addModuleEntity(diff, project.getDisplayName(), Collections.emptyList(), MavenExternalSource.getINSTANCE()); - } - - ModuleEntity finalEntity = entity; - ContentRootEntity contentRootEntity = findFirst(diff, ContentRootEntity.class, e -> e.getModule().equals(finalEntity)); - if (contentRootEntity == null) { - ModifiableProxyBasedImlModelEntitiesKt - .addContentRootEntity(diff, VirtualFileUrlManager.INSTANCE.fromUrl(project.getDirectoryFile().getUrl()), Collections.emptyList(), - Collections.emptyList(), entity, MavenExternalSource.getINSTANCE()); - } - - MavenRootModelAdapter rootModelAdapter = - new MavenRootModelAdapter(new LegacyBridgeMavenRootModelAdapter(project, module, myProject, entity, - (LegacyBrigdeIdeModifiableModelsProvider)myModelsProvider, diff)); - rootModelAdapter.init(isNewModule); - moduleImporter.config(rootModelAdapter); - } - - for (MavenProject project : myAllProjects) { - Module module = myMavenProjectToModule.get(project); - if (module == null) continue; - importers.add(createModuleImporter(module, project, null)); - } - - configFacets(postTasks, importers); - setMavenizedModules(modulesToMavenize, true); - Iterator entities = diff.entities(TypedEntity.class).iterator(); while (entities.hasNext()) { @@ -209,22 +139,30 @@ public class MavenProjectImporter { diff.changeSource(next, MavenExternalSource.getINSTANCE()); } + + // legacy importerss + mapMavenProjectsToModulesAndNames(); + List modulesToMavenize = new ArrayList<>(); + List importers = new ArrayList<>(); for (MavenProject project : myAllProjects) { Module module = myMavenProjectToModule.get(project); if (module == null) continue; - ModuleRootManagerEx.getInstanceEx(module).dropCaches(); + importers.add(createModuleImporter(module, project, null)); } + configFacets(postTasks, importers); + setMavenizedModules(modulesToMavenize, true); + WriteAction.runAndWait(() -> { WorkspaceModel.getInstance(myProject).updateProjectModel(builder -> { builder.replaceBySource(it -> it.equals(MavenExternalSource.getINSTANCE()), diff.toStorage()); return null; }); }); - Disposer.dispose(tempDisposable); return postTasks; } + @Nullable private List importProjectOldWay() { List postTasks = new ArrayList<>(); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapterLegacyImpl.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapterLegacyImpl.java index ad19c00bcf05..8d52d8f040f5 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapterLegacyImpl.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapterLegacyImpl.java @@ -10,7 +10,6 @@ import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; -import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFileManager; @@ -22,6 +21,7 @@ import org.jetbrains.idea.maven.model.MavenArtifact; import org.jetbrains.idea.maven.model.MavenConstants; import org.jetbrains.idea.maven.project.MavenProject; import org.jetbrains.idea.maven.project.MavenProjectsManager; +import org.jetbrains.idea.maven.utils.MavenUtil; import org.jetbrains.idea.maven.utils.Path; import org.jetbrains.idea.maven.utils.Url; import org.jetbrains.jps.model.JpsElement; @@ -266,10 +266,7 @@ public class MavenRootModelAdapterLegacyImpl implements MavenRootModelAdapterInt @Override public Path toPath(String path) { - if (!FileUtil.isAbsolute(path)) { - path = new File(myMavenProject.getDirectory(), path).getPath(); - } - return new Path(path); + return MavenUtil.toPath(myMavenProject, path); } @Override @@ -336,8 +333,7 @@ public class MavenRootModelAdapterLegacyImpl implements MavenRootModelAdapterInt String libraryName = artifact.getLibraryName(); Library library = provider.getLibraryByName(libraryName); - if (library == null) { - library = provider.createLibrary(libraryName, getMavenExternalSource()); + if (library == null) { library = provider.createLibrary(libraryName, getMavenExternalSource()); } Library.ModifiableModel libraryModel = provider.getModifiableLibraryModel(library); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/worktree/LegacyBridgeMavenRootModelAdapter.kt b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/worktree/LegacyBridgeMavenRootModelAdapter.kt index a0dcc35bc65a..d20afaed5cea 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/worktree/LegacyBridgeMavenRootModelAdapter.kt +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/worktree/LegacyBridgeMavenRootModelAdapter.kt @@ -4,21 +4,21 @@ package org.jetbrains.idea.maven.importing.worktree import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project -import com.intellij.openapi.roots.DependencyScope -import com.intellij.openapi.roots.LibraryOrderEntry -import com.intellij.openapi.roots.ModifiableRootModel -import com.intellij.openapi.roots.SourceFolder +import com.intellij.openapi.roots.* import com.intellij.openapi.roots.impl.RootConfigurationAccessor import com.intellij.openapi.roots.libraries.Library import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.pom.java.LanguageLevel import com.intellij.workspace.api.* +import com.intellij.workspace.legacyBridge.intellij.LegacyBridgeCompilerModuleExtension +import com.intellij.workspace.legacyBridge.intellij.LegacyBridgeModule import com.intellij.workspace.legacyBridge.intellij.LegacyBridgeModuleManagerComponent import com.intellij.workspace.legacyBridge.intellij.LegacyBridgeModuleRootComponent import org.jetbrains.idea.maven.importing.MavenModelUtil import org.jetbrains.idea.maven.importing.MavenRootModelAdapterInterface import org.jetbrains.idea.maven.model.MavenArtifact +import org.jetbrains.idea.maven.model.MavenConstants import org.jetbrains.idea.maven.project.MavenProject import org.jetbrains.idea.maven.utils.Path import org.jetbrains.idea.maven.utils.Url @@ -29,13 +29,17 @@ import org.jetbrains.jps.model.module.JpsModuleSourceRootType import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer import java.io.File +@Retention(AnnotationRetention.SOURCE) +private annotation class NotRequiredToImplement; + class LegacyBridgeMavenRootModelAdapter(private val myMavenProject: MavenProject, - private val module: Module, + private val module: LegacyBridgeModule, private val project: Project, - private val moduleEntity: ModuleEntity, + initialModuleEntity: ModuleEntity, private val legacyBridgeModifiableModelsProvider: LegacyBrigdeIdeModifiableModelsProvider, private val builder: TypedEntityStorageBuilder) : MavenRootModelAdapterInterface { + private var moduleEntity: ModuleEntity = initialModuleEntity private val legacyBridge = LegacyBridgeModuleRootComponent.getInstance(module) private val modifiableModel = legacyBridge.getModifiableModel(builder, RootConfigurationAccessor()) private val entitySource = MavenExternalSource.INSTANCE @@ -53,8 +57,9 @@ class LegacyBridgeMavenRootModelAdapter(private val myMavenProject: MavenProject return module } + @NotRequiredToImplement override fun clearSourceFolders() { - TODO("Not Implemented") + } override fun

addSourceFolder(path: String, @@ -135,22 +140,29 @@ class LegacyBridgeMavenRootModelAdapter(private val myMavenProject: MavenProject return moduleEntity.contentRoots.firstOrNull { VfsUtilCore.isEqualOrAncestor(it.url.url, url.url) } } + @NotRequiredToImplement override fun unregisterAll(path: String, under: Boolean, unregisterSources: Boolean) { -// MavenLog.LOG.error("unregisterAll is not implemented") } + @NotRequiredToImplement override fun hasCollision(sourceRootPath: String): Boolean { return false } - override fun useModuleOutput(production: String, test: String) {} + override fun useModuleOutput(production: String, test: String) { + LegacyBridgeCompilerModuleExtension(module, module.entityStore, builder).apply { + inheritCompilerOutputPath(false); + setCompilerOutputPath(toUrl(production).getUrl()); + setCompilerOutputPathForTests(toUrl(test).getUrl()); + } + } override fun addModuleDependency(moduleName: String, scope: DependencyScope, testJar: Boolean) { val dependency = ModuleDependencyItem.Exportable.ModuleDependency(ModuleId(moduleName), false, toEntityScope(scope), testJar) - builder.modifyEntity(ModifiableModuleEntity::class.java, moduleEntity) { + moduleEntity = builder.modifyEntity(ModifiableModuleEntity::class.java, moduleEntity) { this.dependencies = this.dependencies + dependency } } @@ -168,9 +180,24 @@ class LegacyBridgeMavenRootModelAdapter(private val myMavenProject: MavenProject return LegacyBridgeModuleManagerComponent(project).modules.firstOrNull { it.name == moduleName } } + private fun MavenArtifact.ideaLibraryName(): String = "${this.libraryName}"; + override fun addSystemDependency(artifact: MavenArtifact, scope: DependencyScope) { - TODO() + assert(MavenConstants.SCOPE_SYSTEM == artifact.scope) { "Artifact scope should be \"system\"" } + val roots = ArrayList() + roots.add(LibraryRoot(VirtualFileUrlManager.fromUrl(MavenModelUtil.getArtifactUrlForClassifierAndExtension(artifact, null, null)), + LibraryRootTypeId("CLASSES"), + LibraryRoot.InclusionOptions.ROOT_ITSELF)) + + val libraryTableId = LibraryTableId.ModuleLibraryTableId(ModuleId(moduleEntity.name)) + + val libraryEntity = builder.addLibraryEntity(artifact.ideaLibraryName(), libraryTableId, + roots, + emptyList(), entitySource) + + builder.addLibraryPropertiesEntity(libraryEntity, "repository", "", + MavenExternalSource.INSTANCE) } override fun addLibraryDependency(artifact: MavenArtifact, @@ -191,30 +218,38 @@ class LegacyBridgeMavenRootModelAdapter(private val myMavenProject: MavenProject LibraryRootTypeId("SOURCES"), LibraryRoot.InclusionOptions.ROOT_ITSELF)) - val libraryTableId = LibraryTableId.ModuleLibraryTableId(ModuleId(moduleEntity.name)) + val libraryTableId = LibraryTableId.ProjectLibraryTableId; //(ModuleId(moduleEntity.name)) - val libraryEntity = builder.addLibraryEntity(artifact.libraryName, libraryTableId, + val libraryEntity = builder.addLibraryEntity(artifact.ideaLibraryName(), libraryTableId, roots, emptyList(), entitySource) builder.addLibraryPropertiesEntity(libraryEntity, "repository", "", MavenExternalSource.INSTANCE) - val libDependency = ModuleDependencyItem.Exportable.LibraryDependency(LibraryId(libraryEntity.name, libraryTableId), false, toEntityScope(scope)) + val libDependency = ModuleDependencyItem.Exportable.LibraryDependency(LibraryId(libraryEntity.name, libraryTableId), false, + toEntityScope(scope)) - builder.modifyEntity(ModifiableModuleEntity::class.java, moduleEntity, { + moduleEntity = builder.modifyEntity(ModifiableModuleEntity::class.java, moduleEntity, { this.dependencies += this.dependencies + libDependency }) val last = legacyBridge.orderEntries.last() - assert(last is LibraryOrderEntry && last.libraryName == artifact.libraryName) + assert(last is LibraryOrderEntry && last.libraryName == artifact.ideaLibraryName()) return last as LibraryOrderEntry - } override fun findLibrary(artifact: MavenArtifact): Library? { - return legacyBridge.legacyBridgeModuleLibraryTable().libraries.firstOrNull { it.name == artifact.libraryName } + return legacyBridge.legacyBridgeModuleLibraryTable().libraries.firstOrNull { it.name == artifact.ideaLibraryName() } } - override fun setLanguageLevel(level: LanguageLevel) {} + override fun setLanguageLevel(level: LanguageLevel) { + try { + modifiableModel.getModuleExtension(LanguageLevelModuleExtension::class.java)?.apply { + languageLevel = level + } + } + catch (e: IllegalArgumentException) { //bad value was stored + } + } } \ No newline at end of file diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/worktree/LegacyBrigdeIdeModifiableModelsProvider.kt b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/worktree/LegacyBrigdeIdeModifiableModelsProvider.kt index c1471be187e8..b04826f78a81 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/worktree/LegacyBrigdeIdeModifiableModelsProvider.kt +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/worktree/LegacyBrigdeIdeModifiableModelsProvider.kt @@ -26,12 +26,13 @@ import org.jetbrains.idea.maven.utils.MavenLog class LegacyBrigdeIdeModifiableModelsProvider(val project: Project, builder: TypedEntityStorageBuilder) : IdeModifiableModelsProvider { - val diff = builder private val legacyBridgeModuleManagerComponent = LegacyBridgeModuleManagerComponent.getInstance(project) private val myProductionModulesForTestModules = HashMap() private val myUserData = UserDataHolderBase() - private val moduleModel = lazy { + var diff = builder + + private val modifiableModuleModel = lazy { legacyBridgeModuleManagerComponent.getModifiableModel(diff) } @@ -69,14 +70,14 @@ class LegacyBrigdeIdeModifiableModelsProvider(val project: Project, if (moduleTypeId == null) { throw IllegalArgumentException("moduleTypeId") } + val modifiableModel = modifiableModuleModel.value legacyBridgeModuleManagerComponent.incModificationCount() - val modifiableModel = legacyBridgeModuleManagerComponent.getModifiableModel(diff) val module = modifiableModel.newModule(filePath, moduleTypeId) return module } override fun newModule(moduleData: ModuleData): Module { - val modifiableModel = moduleModel.value + val modifiableModel = modifiableModuleModel.value legacyBridgeModuleManagerComponent.incModificationCount() val newModule = modifiableModel.newModule(moduleData.moduleFileDirectoryPath, moduleData.moduleTypeId) return newModule @@ -96,12 +97,12 @@ class LegacyBrigdeIdeModifiableModelsProvider(val project: Project, } override fun getModifiableModuleModel(): ModifiableModuleModel { - return legacyBridgeModuleManagerComponent.getModifiableModel(diff) + return modifiableModuleModel.value } override fun commit() { - if(moduleModel.isInitialized()) { - moduleModel.value.commit() + if(modifiableModuleModel.isInitialized()) { + modifiableModuleModel.value.commit() } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/worktree/WorkspaceModuleImporter.kt b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/worktree/WorkspaceModuleImporter.kt new file mode 100644 index 000000000000..66b83f857691 --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/worktree/WorkspaceModuleImporter.kt @@ -0,0 +1,136 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.jetbrains.idea.maven.importing.worktree + +import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.VfsUtilCore +import com.intellij.workspace.api.* +import org.jetbrains.idea.maven.importing.MavenFoldersImporter +import org.jetbrains.idea.maven.importing.MavenModelUtil +import org.jetbrains.idea.maven.model.MavenArtifact +import org.jetbrains.idea.maven.model.MavenConstants +import org.jetbrains.idea.maven.project.MavenProject +import org.jetbrains.idea.maven.project.MavenProjectsManager +import org.jetbrains.idea.maven.project.MavenProjectsTree +import org.jetbrains.idea.maven.project.SupportedRequestType +import org.jetbrains.jps.model.JpsElement +import org.jetbrains.jps.model.java.JavaResourceRootType +import org.jetbrains.jps.model.java.JavaSourceRootType +import org.jetbrains.jps.model.module.JpsModuleSourceRootType +import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer + +class WorkspaceModuleImporter(private val project: Project, + private val mavenProject: MavenProject, + private val projectsTree: MavenProjectsTree, + private val diff: TypedEntityStorageBuilder) { + + private lateinit var moduleEntity: ModuleEntity + fun importModule() { + val dependencies = collectDependencies(); + moduleEntity = diff.addModuleEntity(mavenProject.displayName, dependencies, MavenExternalSource.INSTANCE) + diff.addContentRootEntity(VirtualFileUrlManager.fromPath(mavenProject.directory), emptyList(), emptyList(), moduleEntity, + MavenExternalSource.INSTANCE) + importFolders() + importLanguageLevel(); + } + + private fun importLanguageLevel() { + //MavenModuleImporter.getLanguageLevel(mavenProject) + } + + private fun collectDependencies(): List { + val dependencyTypes = MavenProjectsManager.getInstance(project).importingSettings.dependencyTypesAsSet; + dependencyTypes.addAll(mavenProject.getDependencyTypesFromImporters(SupportedRequestType.FOR_IMPORT)) + return listOf(ModuleDependencyItem.ModuleSourceDependency, + ModuleDependencyItem.InheritedSdkDependency) + + mavenProject.dependencies.filter { dependencyTypes.contains(it.type) }.mapNotNull(this::createDependency) + + } + + private fun createDependency(artifact: MavenArtifact): ModuleDependencyItem? { + val depProject = projectsTree.findProject(artifact.mavenId) + if (depProject == null) { + return createLibraryDependency(artifact) + } + if (depProject === mavenProject) { + return null + } + if (projectsTree.isIgnored(depProject)) { + TODO() + } + if (artifact.scope == "system") { + TODO() + } + if (artifact.type == "bundle") { + TODO() + } + return createModuleDependency(artifact, depProject) + } + + private fun createModuleDependency(artifact: MavenArtifact, depProject: MavenProject): ModuleDependencyItem { + val isTestJar = MavenConstants.TYPE_TEST_JAR == artifact.type || "tests" == artifact.classifier + return ModuleDependencyItem.Exportable.ModuleDependency(ModuleId(depProject.displayName), false, + toEntityScope(artifact.scope), isTestJar) + } + + private fun createLibraryDependency(artifact: MavenArtifact): ModuleDependencyItem.Exportable.LibraryDependency { + if (!libraryExists(artifact)) { + addLibraryToProjectTable(artifact) + } + val libraryTableId = LibraryTableId.ProjectLibraryTableId; //(ModuleId(moduleEntity.name)) + + return ModuleDependencyItem.Exportable.LibraryDependency(LibraryId(artifact.libraryName, libraryTableId), false, + toEntityScope(artifact.scope)) + } + + private fun libraryExists(artifact: MavenArtifact): Boolean { + return diff.entities(LibraryEntity::class.java).any { it.name == artifact.libraryName } + } + + private fun addLibraryToProjectTable(artifact: MavenArtifact): LibraryEntity { + val roots = ArrayList() + + roots.add(LibraryRoot(VirtualFileUrlManager.fromUrl(MavenModelUtil.getArtifactUrlForClassifierAndExtension(artifact, null, null)), + LibraryRootTypeId("CLASSES"), + LibraryRoot.InclusionOptions.ROOT_ITSELF)) + roots.add( + LibraryRoot(VirtualFileUrlManager.fromUrl(MavenModelUtil.getArtifactUrlForClassifierAndExtension(artifact, "javadoc", "jar")), + LibraryRootTypeId("JAVADOC"), + LibraryRoot.InclusionOptions.ROOT_ITSELF)) + roots.add( + LibraryRoot(VirtualFileUrlManager.fromUrl(MavenModelUtil.getArtifactUrlForClassifierAndExtension(artifact, "sources", "jar")), + LibraryRootTypeId("SOURCES"), + LibraryRoot.InclusionOptions.ROOT_ITSELF)) + + val libraryTableId = LibraryTableId.ProjectLibraryTableId; //(ModuleId(moduleEntity.name)) + + return diff.addLibraryEntity(artifact.libraryName, libraryTableId, + roots, + emptyList(), MavenExternalSource.INSTANCE) + } + + private fun importFolders() { + MavenFoldersImporter.getSourceFolders(mavenProject).forEach { + val sourceRootEntity = diff.addSourceRootEntity(moduleEntity, VirtualFileUrlManager.fromUrl(VfsUtilCore.pathToUrl(it.key)), + it.value.isForTests, + getTypeId(it.value), + MavenExternalSource.INSTANCE) + when (it.value) { + is JavaSourceRootType -> diff.addJavaSourceRootEntity(sourceRootEntity, false, "", MavenExternalSource.INSTANCE) + is JavaResourceRootType -> diff.addJavaResourceRootEntity(sourceRootEntity, false, "", MavenExternalSource.INSTANCE) + else -> TODO() + } + } + } + + fun toEntityScope(mavenScope: String): ModuleDependencyItem.DependencyScope { + if (MavenConstants.SCOPE_RUNTIME == mavenScope) return ModuleDependencyItem.DependencyScope.RUNTIME + if (MavenConstants.SCOPE_TEST == mavenScope) return ModuleDependencyItem.DependencyScope.TEST + return if (MavenConstants.SCOPE_PROVIDED == mavenScope) ModuleDependencyItem.DependencyScope.PROVIDED else ModuleDependencyItem.DependencyScope.COMPILE + } + + + private fun

getTypeId(rootType: JpsModuleSourceRootType

): String { + return if (rootType.isForTests) return JpsModuleRootModelSerializer.JAVA_SOURCE_ROOT_TYPE_ID else JpsModuleRootModelSerializer.JAVA_TEST_ROOT_TYPE_ID + } + +} \ No newline at end of file diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java index 0a1a9c50f742..6f1921f51058 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java @@ -46,7 +46,6 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.io.PathKt; import com.intellij.util.ui.update.Update; import com.intellij.workspace.api.TypedEntityStorageBuilder; -import com.intellij.workspace.legacyBridge.intellij.LegacyBridgeProjectLifecycleListener; import gnu.trove.THashMap; import gnu.trove.THashSet; import org.jetbrains.annotations.ApiStatus; @@ -1234,7 +1233,7 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent } public List importProjects() { - if(LegacyBridgeProjectLifecycleListener.Companion.enabled(myProject)) { + if (MavenUtil.newModelEnabled(myProject)) { TypedEntityStorageBuilder builder = TypedEntityStorageBuilder.Companion.create(); return importProjects(new LegacyBrigdeIdeModifiableModelsProvider(myProject, builder)); } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java index 3136e9c98a8e..f90ac119ca0f 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java @@ -46,6 +46,7 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.VersionComparatorUtil; import com.intellij.util.xml.NanoXmlBuilder; import com.intellij.util.xml.NanoXmlUtil; +import com.intellij.workspace.legacyBridge.intellij.LegacyBridgeProjectLifecycleListener; import gnu.trove.THashSet; import org.jdom.Element; import org.jdom.JDOMException; @@ -731,7 +732,7 @@ public class MavenUtil { if (!isEmptyOrSpaces(overriddenLocalRepository)) result = new File(overriddenLocalRepository); if (result == null) { result = doResolveLocalRepository(resolveUserSettingsFile(overriddenUserSettingsFile), - resolveGlobalSettingsFile(overriddenMavenHome)); + resolveGlobalSettingsFile(overriddenMavenHome)); } try { return result.getCanonicalFile(); @@ -884,6 +885,10 @@ public class MavenUtil { } } + public static boolean newModelEnabled(Project project) { + return LegacyBridgeProjectLifecycleListener.Companion.enabled(project); + } + public interface MavenTaskHandler { void waitFor(); } @@ -1153,4 +1158,14 @@ public class MavenUtil { } return null; } + + public static Path toPath(@Nullable MavenProject mavenProject, String path) { + if (!FileUtil.isAbsolute(path)) { + if(mavenProject == null) { + throw new IllegalArgumentException("Project should be not-nul for non-absolute paths"); + } + path = new File(mavenProject.getDirectory(), path).getPath(); + } + return new Path(path); + } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenProjectBuilder.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenProjectBuilder.java index 9d7ce11623c6..178b8dcfff1b 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenProjectBuilder.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenProjectBuilder.java @@ -21,7 +21,6 @@ import com.intellij.packaging.artifacts.ModifiableArtifactModel; import com.intellij.projectImport.DeprecatedProjectBuilderForImport; import com.intellij.projectImport.ProjectImportBuilder; import com.intellij.projectImport.ProjectOpenProcessor; -import com.intellij.workspace.legacyBridge.intellij.LegacyBridgeProjectLifecycleListener; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -198,7 +197,7 @@ public class MavenProjectBuilder extends ProjectImportBuilder impl } boolean isFromUI = model != null; - if (isFromUI && LegacyBridgeProjectLifecycleListener.Companion.enabled(project)) { + if (isFromUI && MavenUtil.newModelEnabled(project)) { throw new UnsupportedOperationException(); //return manager.importProjects(new IdeUIModifiableModelsProvider(project, model, (ModulesConfigurator)modulesProvider, artifactModel)); } diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/DependenciesImportingTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/DependenciesImportingTest.java index 9408a8b66122..cb7807b46227 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/DependenciesImportingTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/DependenciesImportingTest.java @@ -1654,16 +1654,16 @@ public class DependenciesImportingTest extends MavenImportingTestCase { ""); importProject("test" + - "project" + - "1" + - "pom" + + "project" + + "1" + + "pom" + - "" + - " m1" + - " m2" + - ""); + "" + + " m1" + + " m2" + + ""); -// assertProjectLibraries("Maven: xxx:yyy:1"); + // assertProjectLibraries("Maven: xxx:yyy:1"); assertModuleLibDep("m1", "Maven: xxx:yyy:1", "jar://" + getRoot() + "/m1/foo.jar!/"); assertModuleLibDep("m2", "Maven: xxx:yyy:1", "jar://" + getRoot() + "/m2/foo.jar!/"); }