mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-04 23:39:07 +07:00
[maven] IDEA-272727 fix maven encoding configurer.
Revert to batch processing, but use new EncodingProjectManagerImpl.setPointerMapping and VirtualFilePointers instead of VirtualFiles. GitOrigin-RevId: 4a69146e2dfe192b7bfaf32bd00d5e71e0396ae2
This commit is contained in:
committed by
intellij-monorepo-bot
parent
efda1da73e
commit
862f10fee6
@@ -3,7 +3,6 @@ package com.intellij.openapi.vfs.encoding;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
@@ -31,12 +30,4 @@ public abstract class EncodingProjectManager extends EncodingManager {
|
||||
*/
|
||||
@Override
|
||||
public abstract void setDefaultCharsetName(@NotNull String name);
|
||||
|
||||
/**
|
||||
* Sets encoding by file / dir path.
|
||||
* The target file or directory may not exist.
|
||||
* @param fileOrDirPath target file / dir absolute path
|
||||
* @param charset null to remove specific configuration.
|
||||
*/
|
||||
public abstract void setEncodingByPath(@NotNull final String fileOrDirPath, @Nullable final Charset charset);
|
||||
}
|
||||
|
||||
@@ -34,10 +34,6 @@ public class CoreEncodingProjectManager extends EncodingProjectManager {
|
||||
public void setEncoding(@Nullable VirtualFile virtualFileOrDir, @Nullable Charset charset) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEncodingByPath(@NotNull String path, @Nullable Charset charset) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNative2AsciiForPropertiesFiles() {
|
||||
return false;
|
||||
|
||||
@@ -23,7 +23,10 @@ import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.startup.StartupActivity;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.text.StringUtilRt;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileVisitor;
|
||||
import com.intellij.openapi.vfs.impl.LightFilePointer;
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry;
|
||||
@@ -202,28 +205,6 @@ public final class EncodingProjectManagerImpl extends EncodingProjectManager imp
|
||||
return myModificationTracker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEncodingByPath(@NotNull final String fileOrDirPath, @Nullable final Charset charset) {
|
||||
final VirtualFile vf = LocalFileSystem.getInstance().findFileByPath(fileOrDirPath);
|
||||
if (vf != null) {
|
||||
setEncoding(vf, charset);
|
||||
return;
|
||||
}
|
||||
|
||||
Charset oldCharset;
|
||||
VirtualFilePointer pointer = VirtualFilePointerManager.getInstance().create(VfsUtilCore.pathToUrl(fileOrDirPath), this, null);
|
||||
if (charset == null) {
|
||||
oldCharset = myMapping.remove(pointer);
|
||||
}
|
||||
else {
|
||||
oldCharset = myMapping.put(pointer, charset);
|
||||
}
|
||||
|
||||
if (!Comparing.equal(oldCharset, charset)) {
|
||||
myModificationTracker.incModificationCount();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEncoding(@Nullable final VirtualFile virtualFileOrDir, @Nullable final Charset charset) {
|
||||
Charset oldCharset;
|
||||
@@ -300,11 +281,18 @@ public final class EncodingProjectManagerImpl extends EncodingProjectManager imp
|
||||
.collect(Collectors.toMap(p -> p.getFirst(), p -> p.getSecond(), (c1, c2) -> c1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return readonly map of current mappings. to modify mappings use {@link #setPointerMapping(Map)}
|
||||
*/
|
||||
@NotNull
|
||||
public Map<? extends VirtualFilePointer, ? extends Charset> getAllPointersMappings() {
|
||||
return Collections.unmodifiableMap(myMapping);
|
||||
}
|
||||
|
||||
public void setMapping(@NotNull Map<? extends VirtualFile, ? extends Charset> mapping) {
|
||||
ApplicationManager.getApplication().assertIsWriteThread();
|
||||
FileDocumentManager.getInstance().saveAllDocuments(); // consider all files as unmodified
|
||||
final Map<VirtualFilePointer, Charset> newMap = new HashMap<>(mapping.size());
|
||||
final Map<VirtualFilePointer, Charset> oldMap = new HashMap<>(myMapping);
|
||||
|
||||
// ChangeFileEncodingAction should not start progress "reload files..."
|
||||
suppressReloadDuring(() -> {
|
||||
@@ -320,27 +308,47 @@ public final class EncodingProjectManagerImpl extends EncodingProjectManager imp
|
||||
if (!fileIndex.isInContent(virtualFile)) continue;
|
||||
VirtualFilePointer pointer = VirtualFilePointerManager.getInstance().create(virtualFile, this, null);
|
||||
|
||||
if (!virtualFile.isDirectory() && !Comparing.equal(charset, oldMap.get(pointer))) {
|
||||
Document document;
|
||||
byte[] bytes;
|
||||
try {
|
||||
document = FileDocumentManager.getInstance().getDocument(virtualFile);
|
||||
if (document == null) throw new IOException();
|
||||
bytes = virtualFile.contentsToByteArray();
|
||||
}
|
||||
catch (IOException e) {
|
||||
continue;
|
||||
}
|
||||
// ask whether to reload/convert when in doubt
|
||||
boolean changed = new ChangeFileEncodingAction().chosen(document, null, virtualFile, bytes, charset);
|
||||
|
||||
if (!changed) continue;
|
||||
}
|
||||
if (!fileEncodingChanged(virtualFile, myMapping.get(pointer), charset)) continue;
|
||||
newMap.put(pointer, charset);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
updateMapping(newMap);
|
||||
}
|
||||
|
||||
|
||||
public void setPointerMapping(@NotNull Map<? extends VirtualFilePointer, ? extends Charset> mapping) {
|
||||
ApplicationManager.getApplication().assertIsWriteThread();
|
||||
FileDocumentManager.getInstance().saveAllDocuments(); // consider all files as unmodified
|
||||
final Map<VirtualFilePointer, Charset> newMap = new HashMap<>(mapping.size());
|
||||
|
||||
// ChangeFileEncodingAction should not start progress "reload files..."
|
||||
suppressReloadDuring(() -> {
|
||||
ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
|
||||
for (Map.Entry<? extends VirtualFilePointer, ? extends Charset> entry : mapping.entrySet()) {
|
||||
VirtualFilePointer filePointer = entry.getKey();
|
||||
Charset charset = entry.getValue();
|
||||
if (charset == null) throw new IllegalArgumentException("Null charset for " + filePointer + "; mapping: " + mapping);
|
||||
if (filePointer == null) {
|
||||
myProjectCharset = charset;
|
||||
}
|
||||
else {
|
||||
final VirtualFile virtualFile = filePointer.getFile();
|
||||
if (virtualFile != null) {
|
||||
if (!fileIndex.isInContent(virtualFile)
|
||||
|| !fileEncodingChanged(virtualFile, myMapping.get(filePointer), charset)) continue;
|
||||
}
|
||||
newMap.put(filePointer, charset);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
updateMapping(newMap);
|
||||
}
|
||||
|
||||
private void updateMapping(Map<VirtualFilePointer, Charset> newMap) {
|
||||
Map<VirtualFilePointer, Charset> oldMap = new HashMap<>(myMapping);
|
||||
myMapping.clear();
|
||||
myMapping.putAll(newMap);
|
||||
|
||||
@@ -384,6 +392,26 @@ public final class EncodingProjectManagerImpl extends EncodingProjectManager imp
|
||||
myModificationTracker.incModificationCount();
|
||||
}
|
||||
|
||||
private static boolean fileEncodingChanged(@NotNull VirtualFile virtualFile,
|
||||
@Nullable Charset oldCharset,
|
||||
@NotNull Charset newCharset) {
|
||||
if (!virtualFile.isDirectory() && !Comparing.equal(newCharset, oldCharset)) {
|
||||
Document document;
|
||||
byte[] bytes;
|
||||
try {
|
||||
document = FileDocumentManager.getInstance().getDocument(virtualFile);
|
||||
if (document == null) throw new IOException();
|
||||
bytes = virtualFile.contentsToByteArray();
|
||||
}
|
||||
catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
// ask whether to reload/convert when in doubt
|
||||
return new ChangeFileEncodingAction().chosen(document, null, virtualFile, bytes, newCharset);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Processor<VirtualFile> createChangeCharsetProcessor(@NotNull Project project) {
|
||||
return file -> {
|
||||
|
||||
@@ -15,9 +15,19 @@
|
||||
*/
|
||||
package org.jetbrains.idea.maven.importing.configurers
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.ReadAction
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.VfsUtil.fileToUrl
|
||||
import com.intellij.openapi.vfs.VfsUtilCore.urlToPath
|
||||
import com.intellij.openapi.vfs.encoding.EncodingProjectManager
|
||||
import com.intellij.openapi.vfs.encoding.EncodingProjectManagerImpl
|
||||
import com.intellij.openapi.vfs.pointers.VirtualFilePointer
|
||||
import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager
|
||||
import org.jetbrains.idea.maven.project.MavenProject
|
||||
import org.jetbrains.idea.maven.utils.MavenLog
|
||||
import java.io.File
|
||||
@@ -29,26 +39,70 @@ import java.nio.charset.UnsupportedCharsetException
|
||||
*/
|
||||
class MavenEncodingConfigurer : MavenModuleConfigurer() {
|
||||
override fun configure(mavenProject: MavenProject, project: Project, module: Module) {
|
||||
fillSourceEncoding(mavenProject, EncodingProjectManager.getInstance(project))
|
||||
fillResourceEncoding(project, mavenProject, EncodingProjectManager.getInstance(project))
|
||||
val encodingCollector = EncodingCollector(project)
|
||||
|
||||
ReadAction.compute<Unit, Throwable> {
|
||||
fillSourceEncoding(mavenProject, encodingCollector)
|
||||
}
|
||||
|
||||
ReadAction.compute<Unit, Throwable> {
|
||||
fillResourceEncoding(project, mavenProject, encodingCollector)
|
||||
}
|
||||
|
||||
encodingCollector.applyCollectedInfo()
|
||||
}
|
||||
|
||||
private fun fillResourceEncoding(project: Project,
|
||||
mavenProject: MavenProject,
|
||||
projectManager: EncodingProjectManager) {
|
||||
mavenProject.getResourceEncoding(project)?.let(this::getCharset)?.let { charset ->
|
||||
mavenProject.resources.forEach { resource ->
|
||||
projectManager.setEncodingByPath(File(resource.directory).absolutePath, charset)
|
||||
class EncodingCollector(project: Project) {
|
||||
private val newPointerMappings = LinkedHashMap<VirtualFilePointer, Charset>()
|
||||
private val oldPointerMappings = LinkedHashMap<VirtualFilePointer, Charset>()
|
||||
private val encodingManager = (EncodingProjectManager.getInstance(project) as EncodingProjectManagerImpl)
|
||||
|
||||
fun processDir(directory: String, charset: Charset) {
|
||||
val dirVfile = LocalFileSystem.getInstance().findFileByIoFile(File(directory))
|
||||
val pointer = if (dirVfile != null) {
|
||||
service<VirtualFilePointerManager>().create(dirVfile, encodingManager, null)
|
||||
} else {
|
||||
service<VirtualFilePointerManager>().create(fileToUrl(File(directory).absoluteFile), encodingManager, null)
|
||||
}
|
||||
newPointerMappings[pointer] = charset
|
||||
encodingManager.allPointersMappings.forEach {
|
||||
val filePointer = it.key
|
||||
if (FileUtil.isAncestor(directory, urlToPath(filePointer.url), false)
|
||||
|| newPointerMappings.containsKey(filePointer)) {
|
||||
newPointerMappings[filePointer] = charset
|
||||
oldPointerMappings.remove(filePointer)
|
||||
}
|
||||
else {
|
||||
oldPointerMappings[filePointer] = it.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun applyCollectedInfo() {
|
||||
if (newPointerMappings.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
val pointerMapping = newPointerMappings + oldPointerMappings
|
||||
|
||||
ApplicationManager.getApplication().invokeAndWait {
|
||||
encodingManager.setPointerMapping(pointerMapping)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun fillResourceEncoding(project: Project,
|
||||
mavenProject: MavenProject,
|
||||
encodingCollector: EncodingCollector) {
|
||||
mavenProject.getResourceEncoding(project)?.let(this::getCharset)?.let { charset ->
|
||||
mavenProject.resources.map { it.directory }.forEach { encodingCollector.processDir(it, charset) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun fillSourceEncoding(mavenProject: MavenProject,
|
||||
projectManager: EncodingProjectManager) {
|
||||
encodingCollector: EncodingCollector) {
|
||||
mavenProject.sourceEncoding?.let(this::getCharset)?.let { charset ->
|
||||
mavenProject.sources.forEach { directory ->
|
||||
projectManager.setEncodingByPath(File(directory).absolutePath, charset)
|
||||
}
|
||||
mavenProject.sources.forEach { encodingCollector.processDir(it, charset) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user