SVN: bug with encoding != UTF-8

This commit is contained in:
irengrig
2011-09-26 09:41:41 +04:00
parent d12dbd429c
commit 3f041965ea
8 changed files with 42 additions and 13 deletions
@@ -75,6 +75,8 @@ public interface FilePath {
void refresh();
void hardRefresh();
String getPath();
/**
@@ -33,6 +33,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Set;
@@ -137,7 +138,7 @@ public class ContentRevisionCache {
if (path.getVirtualFile() != null) {
charset = path.getVirtualFile().getCharset();
}
return charset == null ? CharsetToolkit.bytesToString(bytes) : CharsetToolkit.bytesToString(bytes, charset);
return charset == null ? CharsetToolkit.bytesToString(bytes) : charset.decode(ByteBuffer.wrap(bytes)).toString();
}
@Nullable
@@ -108,6 +108,12 @@ public class FilePathImpl implements FilePath {
}
}
public void hardRefresh() {
if (! myNonLocal && (myVirtualFile == null || ! myVirtualFile.isValid())) {
myVirtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(myFile);
}
}
public String getPath() {
final VirtualFile virtualFile = myVirtualFile;
if (virtualFile != null && virtualFile.isValid()) {
@@ -25,10 +25,7 @@ import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vcs.AbstractVcsHelper;
import com.intellij.openapi.vcs.RepositoryLocation;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.util.ArrayUtil;
import com.intellij.util.NotNullFunction;
@@ -47,6 +44,8 @@ import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.wc.*;
import java.io.File;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.*;
public class SvnUtil {
@@ -664,4 +663,11 @@ public class SvnUtil {
}
}
}
public static byte[] decode(final Charset charset, final byte[] buffer) {
if (charset != null && ! CharsetToolkit.UTF8_CHARSET.equals(charset)) {
return CharsetToolkit.UTF8_CHARSET.encode(charset.decode(ByteBuffer.wrap(buffer))).array();
}
return buffer;
}
}
@@ -36,6 +36,7 @@ import org.tmatesoft.svn.core.wc.*;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.*;
public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAnnotationProvider {
@@ -52,7 +53,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
throw new VcsException("Can not get current revision for file " + file.getPath());
}
final SVNRevision svnRevision = currentRevision.getRevision();
return annotate(file, new SvnFileRevision(myVcs, svnRevision, svnRevision, null, null, null, null, null), true);
return annotate(file, new SvnFileRevision(myVcs, svnRevision, svnRevision, null, null, null, null, null, file.getCharset()), true);
}
public FileAnnotation annotate(final VirtualFile file, final VcsFileRevision revision) throws VcsException {
@@ -109,7 +110,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
SvnUtil.checkRepositoryVersion15(myVcs, url);
final SVNRevision svnRevision = ((SvnRevisionNumber)revision.getRevisionNumber()).getRevision();
final MySteppedLogGetter logGetter = new MySteppedLogGetter(myVcs, ioFile, progress, client, endRevision, result, url, calculateMergeinfo);
final MySteppedLogGetter logGetter = new MySteppedLogGetter(myVcs, ioFile, progress, client, endRevision, result, url, calculateMergeinfo, file.getCharset());
logGetter.go();
final LinkedList<SVNRevision> rp = logGetter.getRevisionPoints();
@@ -274,9 +275,14 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
private final boolean myCalculateMergeinfo;
private final SvnFileAnnotation myResult;
private final String myUrl;
private final Charset myCharset;
private MySteppedLogGetter(final SvnVcs vcs, final File ioFile, final ProgressIndicator progress, final SVNLogClient client,
final SVNRevision endRevision, final SvnFileAnnotation result, final String url, final boolean calculateMergeinfo) {
final SVNRevision endRevision,
final SvnFileAnnotation result,
final String url,
final boolean calculateMergeinfo,
Charset charset) {
myVcs = vcs;
myIoFile = ioFile;
myProgress = progress;
@@ -285,6 +291,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
myCalculateMergeinfo = calculateMergeinfo;
myResult = result;
myUrl = url;
myCharset = charset;
myRevisionPoints = new LinkedList<SVNRevision>();
}
@@ -343,7 +350,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
myProgress.checkCanceled();
myProgress.setText2(SvnBundle.message("progress.text2.revision.processed", logEntry.getRevision()));
}
myResult.setRevision(logEntry.getRevision(), new SvnFileRevision(myVcs, SVNRevision.UNDEFINED, logEntry, myUrl, ""));
myResult.setRevision(logEntry.getRevision(), new SvnFileRevision(myVcs, SVNRevision.UNDEFINED, logEntry, myUrl, "", myCharset));
}
});
}
@@ -233,7 +233,7 @@ public class RepositoryBrowserComponent extends JPanel implements Disposable, Da
if (entry.getName().lastIndexOf('.') > 0 && !manager.getFileTypeByFileName(name).isBinary()) {
SVNURL url = node.getURL();
final SvnFileRevision revision = new SvnFileRevision(myVCS, SVNRevision.UNDEFINED, SVNRevision.HEAD, url.toString(),
entry.getAuthor(), entry.getDate(), null, null);
entry.getAuthor(), entry.getDate(), null, null, null);
return new VcsVirtualFile(node.getSVNDirEntry().getName(), revision, VcsFileSystem.getInstance());
} else {
@@ -27,6 +27,7 @@ import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.impl.ContentRevisionCache;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnRevisionNumber;
import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.SvnVcs;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNLogEntry;
@@ -37,6 +38,7 @@ import org.tmatesoft.svn.core.wc.SVNWCClient;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -54,6 +56,7 @@ public class SvnFileRevision implements VcsFileRevision {
private final SVNRevision myRevision;
private final String myCopyFromPath;
private final List<SvnFileRevision> myMergeSources;
private final Charset myCharset;
public SvnFileRevision(SvnVcs vcs,
SVNRevision pegRevision,
@@ -62,7 +65,8 @@ public class SvnFileRevision implements VcsFileRevision {
String author,
Date date,
String commitMessage,
String copyFromPath) {
String copyFromPath, Charset charset) {
myCharset = charset;
myRevisionNumber = new SvnRevisionNumber(revision);
myPegRevision = pegRevision;
myRevision = revision;
@@ -79,7 +83,8 @@ public class SvnFileRevision implements VcsFileRevision {
SVNRevision pegRevision,
SVNLogEntry logEntry,
String url,
String copyFromPath) {
String copyFromPath, Charset charset) {
myCharset = charset;
final SVNRevision revision = SVNRevision.create(logEntry.getRevision());
myRevisionNumber = new SvnRevisionNumber(revision);
myPegRevision = pegRevision;
@@ -157,7 +162,8 @@ public class SvnFileRevision implements VcsFileRevision {
new Throwable2Computable<byte[], VcsException, IOException>() {
@Override
public byte[] compute() throws VcsException, IOException {
return loadContent();
byte[] bytes = loadContent();
return SvnUtil.decode(myCharset, bytes);
}
});
}
@@ -71,6 +71,7 @@ public class SvnRepositoryContentRevision implements ContentRevision {
@Nullable
public String getContent() throws VcsException {
try {
myFilePath.hardRefresh();
return ContentRevisionCache.getOrLoadAsString(myVcs.getProject(), myFilePath, getRevisionNumber(), myVcs.getKeyInstanceMethod(),
ContentRevisionCache.UniqueType.REPOSITORY_CONTENT, new Throwable2Computable<byte[], VcsException, IOException>() {
@Override