mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
maven new model import - do not use RootModel
GitOrigin-RevId: 1d09ac93b42b2339f5e67ada0795b2c85a65a06c
This commit is contained in:
committed by
intellij-monorepo-bot
parent
bb83c4e620
commit
4ebed60d95
+37
-16
@@ -105,40 +105,61 @@ public class MavenFoldersImporter {
|
||||
}
|
||||
|
||||
private void configSourceFolders() {
|
||||
Map<String, JpsModuleSourceRootType<?>> sourceFolders = getSourceFolders(myMavenProject);
|
||||
|
||||
sourceFolders.forEach((p, t) -> myModel.addSourceFolder(p, t));
|
||||
}
|
||||
|
||||
private static boolean alreadyAdded(String canonicalPath, Map<String, ?> addedPaths) {
|
||||
for (String existing : addedPaths.keySet()) {
|
||||
if (VfsUtilCore.isEqualOrAncestor(existing, canonicalPath)
|
||||
|| VfsUtilCore.isEqualOrAncestor(canonicalPath, existing)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Map<String, JpsModuleSourceRootType<?>> getSourceFolders(MavenProject mavenProject) {
|
||||
final MultiMap<JpsModuleSourceRootType<?>, 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<String> addedPaths = new ArrayList<>();
|
||||
Map<String, JpsModuleSourceRootType<?>> 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<String> folders) {
|
||||
final MavenPlugin plugin = myMavenProject.findPlugin("org.codehaus.mojo", "build-helper-maven-plugin");
|
||||
private static void addBuilderHelperPaths(MavenProject mavenProject, String goal, Collection<String> 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<String> folders) {
|
||||
final MavenPlugin plugin = myMavenProject.findPlugin("org.codehaus.mojo", "build-helper-maven-plugin");
|
||||
private static void addBuilderHelperResourcesPaths(MavenProject mavenProject, String goal, Collection<String> 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)) {
|
||||
|
||||
+13
-7
@@ -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) {
|
||||
|
||||
+23
-85
@@ -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<MavenProjectsProcessorTask> 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<MavenProject> projectsWithNewlyCreatedModules = new THashSet<>();
|
||||
Map<MavenProject, ModuleEntity> 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<Module> modulesToMavenize = new ArrayList<>();
|
||||
List<MavenModuleImporter> 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<TypedEntity> 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<Module> modulesToMavenize = new ArrayList<>();
|
||||
List<MavenModuleImporter> 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).<Void>updateProjectModel(builder -> {
|
||||
builder.replaceBySource(it -> it.equals(MavenExternalSource.getINSTANCE()), diff.toStorage());
|
||||
return null;
|
||||
});
|
||||
});
|
||||
Disposer.dispose(tempDisposable);
|
||||
return postTasks;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private List<MavenProjectsProcessorTask> importProjectOldWay() {
|
||||
List<MavenProjectsProcessorTask> postTasks = new ArrayList<>();
|
||||
|
||||
+3
-7
@@ -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);
|
||||
|
||||
|
||||
+54
-19
@@ -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 <P : JpsElement?> 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<LibraryRoot>()
|
||||
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", "<properties maven-id=\"${artifact.mavenId}\" />",
|
||||
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", "<properties maven-id=\"${artifact.mavenId}\" />",
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+8
-7
@@ -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<Module, String>()
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+136
@@ -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<ModuleDependencyItem> {
|
||||
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<LibraryRoot>()
|
||||
|
||||
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 <P : JpsElement?> getTypeId(rootType: JpsModuleSourceRootType<P>): String {
|
||||
return if (rootType.isForTests) return JpsModuleRootModelSerializer.JAVA_SOURCE_ROOT_TYPE_ID else JpsModuleRootModelSerializer.JAVA_TEST_ROOT_TYPE_ID
|
||||
}
|
||||
|
||||
}
|
||||
+1
-2
@@ -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<Module> importProjects() {
|
||||
if(LegacyBridgeProjectLifecycleListener.Companion.enabled(myProject)) {
|
||||
if (MavenUtil.newModelEnabled(myProject)) {
|
||||
TypedEntityStorageBuilder builder = TypedEntityStorageBuilder.Companion.create();
|
||||
return importProjects(new LegacyBrigdeIdeModifiableModelsProvider(myProject, builder));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -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<MavenProject> 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));
|
||||
}
|
||||
|
||||
+8
-8
@@ -1654,16 +1654,16 @@ public class DependenciesImportingTest extends MavenImportingTestCase {
|
||||
"</dependencies>");
|
||||
|
||||
importProject("<groupId>test</groupId>" +
|
||||
"<artifactId>project</artifactId>" +
|
||||
"<version>1</version>" +
|
||||
"<packaging>pom</packaging>" +
|
||||
"<artifactId>project</artifactId>" +
|
||||
"<version>1</version>" +
|
||||
"<packaging>pom</packaging>" +
|
||||
|
||||
"<modules>" +
|
||||
" <module>m1</module>" +
|
||||
" <module>m2</module>" +
|
||||
"</modules>");
|
||||
"<modules>" +
|
||||
" <module>m1</module>" +
|
||||
" <module>m2</module>" +
|
||||
"</modules>");
|
||||
|
||||
// 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!/");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user