vcs: implement ByteBackedContentRevision

This commit is contained in:
Aleksey Pivovarov
2015-12-23 15:05:11 +03:00
parent e5778be3a3
commit fb639a0e6c
10 changed files with 129 additions and 106 deletions
@@ -80,10 +80,10 @@ public class VcsCurrentRevisionProxy implements ContentRevision {
private ContentRevision getVcsRevision() throws VcsException {
final FilePath file = getFile();
final Pair<VcsRevisionNumber, String> pair;
final Pair<VcsRevisionNumber, byte[]> pair;
try {
pair = ContentRevisionCache.getOrLoadCurrentAsString(myProject, file, myVcsKey,
new CurrentRevisionProvider() {
pair = ContentRevisionCache.getOrLoadCurrentAsBytes(myProject, file, myVcsKey,
new CurrentRevisionProvider() {
@Override
public VcsRevisionNumber getCurrentRevision() throws VcsException {
return getCurrentRevisionNumber();
@@ -99,9 +99,16 @@ public class VcsCurrentRevisionProxy implements ContentRevision {
throw new VcsException(e);
}
return new ContentRevision() {
return new ByteBackedContentRevision() {
@Override
public String getContent() throws VcsException {
byte[] byteContent = getContentAsBytes();
return ContentRevisionCache.getAsString(byteContent, file, null);
}
@Nullable
@Override
public byte[] getContentAsBytes() throws VcsException {
return pair.getSecond();
}
@@ -1223,7 +1223,7 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton {
return null;
}
private static class LoadedContentRevision implements ContentRevision {
private static class LoadedContentRevision implements ByteBackedContentRevision {
private final FilePath myFile;
private final VcsFileRevision myRevision;
private final Project myProject;
@@ -1243,6 +1243,17 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton {
}
}
@Nullable
@Override
public byte[] getContentAsBytes() throws VcsException {
try {
return VcsHistoryUtil.loadRevisionContent(myRevision);
}
catch (IOException e) {
throw new VcsException(VcsBundle.message("message.text.cannot.load.revision", e.getLocalizedMessage()));
}
}
@NotNull
public FilePath getFile() {
return myFile;
@@ -42,10 +42,7 @@ public class CvsBinaryContentRevision extends CvsContentRevision implements Bina
@Nullable
public byte[] getBinaryContent() throws VcsException {
if (myContent == null) {
myContent = loadContent();
}
return myContent;
return getContentAsBytes();
}
@Override @NonNls
@@ -35,7 +35,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.actions.VcsContextFactory;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.changes.ByteBackedContentRevision;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vfs.CharsetToolkit;
import org.jetbrains.annotations.NonNls;
@@ -43,16 +43,15 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.nio.charset.Charset;
public class CvsContentRevision implements ContentRevision {
public class CvsContentRevision implements ByteBackedContentRevision {
protected final RevisionOrDate myRevision;
protected final File myFile;
private final FilePath myLocalFile;
private final CvsEnvironment myEnvironment;
private final Project myProject;
private String myContent;
private byte[] myContent;
public CvsContentRevision(final File file,
final File localFile,
@@ -68,34 +67,33 @@ public class CvsContentRevision implements ContentRevision {
@Nullable
public String getContent() throws VcsException {
if (myContent == null) {
byte[] content = loadContent();
if (content != null) {
final Charset charset = myLocalFile.getCharset();
myContent = CharsetToolkit.bytesToString(content, charset);
}
}
return myContent;
byte[] content = getContentAsBytes();
return content == null ? null : CharsetToolkit.bytesToString(content, myLocalFile.getCharset());
}
protected byte[] loadContent() throws VcsException {
final GetFileContentOperation operation = new GetFileContentOperation(myFile, myEnvironment, myRevision);
CvsOperationExecutor executor = new CvsOperationExecutor(myProject);
executor.performActionSync(new CommandCvsHandler(CvsBundle.message("operation.name.load.file"),
operation),
CvsOperationExecutorCallback.EMPTY);
CvsResult result = executor.getResult();
if (result.isCanceled()) {
throw new ProcessCanceledException();
}
if (result.hasErrors()) {
throw result.composeError();
}
if (!operation.isLoaded()) {
throw new VcsException("Network problem");
}
@Nullable
@Override
public byte[] getContentAsBytes() throws VcsException {
if (myContent == null) {
final GetFileContentOperation operation = new GetFileContentOperation(myFile, myEnvironment, myRevision);
CvsOperationExecutor executor = new CvsOperationExecutor(myProject);
executor.performActionSync(new CommandCvsHandler(CvsBundle.message("operation.name.load.file"),
operation),
CvsOperationExecutorCallback.EMPTY);
CvsResult result = executor.getResult();
if (result.isCanceled()) {
throw new ProcessCanceledException();
}
if (result.hasErrors()) {
throw result.composeError();
}
if (!operation.isLoaded()) {
throw new VcsException("Network problem");
}
return operation.getFileBytes();
myContent = operation.getFileBytes();
}
return myContent;
}
@NotNull
@@ -506,10 +506,11 @@ public class CvsChangeProvider implements ChangeProvider {
return result;
}
private class CvsUpToDateRevision implements ContentRevision {
private class CvsUpToDateRevision implements ByteBackedContentRevision {
protected final FilePath myPath;
private final VcsRevisionNumber myRevisionNumber;
private String myContent;
private byte[] myContent;
protected CvsUpToDateRevision(final FilePath path, final VcsRevisionNumber revisionNumber) {
myRevisionNumber = revisionNumber;
@@ -519,20 +520,26 @@ public class CvsChangeProvider implements ChangeProvider {
@Override
@Nullable
public String getContent() throws VcsException {
final byte[] fileBytes = getContentAsBytes();
return fileBytes == null ? null : CharsetToolkit.bytesToString(fileBytes, myPath.getCharset());
}
@Nullable
@Override
public byte[] getContentAsBytes() throws VcsException {
if (myContent == null) {
try {
final byte[] fileBytes = getUpToDateBinaryContent();
myContent = fileBytes == null ? null : CharsetToolkit.bytesToString(fileBytes, myPath.getCharset());
myContent = getUpToDateBinaryContent();
}
catch (CannotFindCvsRootException e) {
myContent = null;
throw new VcsException(e);
}
}
return myContent;
}
@Nullable
protected byte[] getUpToDateBinaryContent() throws CannotFindCvsRootException {
private byte[] getUpToDateBinaryContent() throws CannotFindCvsRootException {
final VirtualFile virtualFile = myPath.getVirtualFile();
byte[] result = null;
if (virtualFile != null) {
@@ -585,8 +592,6 @@ public class CvsChangeProvider implements ChangeProvider {
}
private class CvsUpToDateBinaryRevision extends CvsUpToDateRevision implements BinaryContentRevision {
private byte[] myBinaryContent;
public CvsUpToDateBinaryRevision(final FilePath path, final VcsRevisionNumber revisionNumber) {
super(path, revisionNumber);
}
@@ -594,15 +599,7 @@ public class CvsChangeProvider implements ChangeProvider {
@Override
@Nullable
public byte[] getBinaryContent() throws VcsException {
if (myBinaryContent == null) {
try {
myBinaryContent = getUpToDateBinaryContent();
}
catch (CannotFindCvsRootException e) {
throw new VcsException(e);
}
}
return myBinaryContent;
return getContentAsBytes();
}
@NonNls
@@ -16,14 +16,14 @@ import com.google.common.base.Objects;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.changes.ByteBackedContentRevision;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.util.HgUtil;
public class HgContentRevision implements ContentRevision {
public class HgContentRevision implements ByteBackedContentRevision {
private final Project myProject;
@NotNull private final HgFile myHgFile;
@@ -35,12 +35,7 @@ class SvnBinaryContentRevision extends SvnContentRevision implements BinaryConte
@Nullable
public byte[] getBinaryContent() throws VcsException {
try {
return getUpToDateBinaryContent();
}
catch(Exception ex) {
throw new VcsException(ex);
}
return getContentAsBytes();
}
@NonNls
@@ -21,7 +21,7 @@ import com.intellij.openapi.util.Throwable2Computable;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.changes.ByteBackedContentRevision;
import com.intellij.openapi.vcs.changes.MarkerVcsContentRevision;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.impl.ContentRevisionCache;
@@ -39,7 +39,7 @@ import java.io.IOException;
/**
* @author yole
*/
public class SvnContentRevision implements ContentRevision, MarkerVcsContentRevision {
public class SvnContentRevision implements ByteBackedContentRevision, MarkerVcsContentRevision {
@NotNull private final SvnVcs myVcs;
@NotNull protected final FilePath myFile;
@@ -81,30 +81,36 @@ public class SvnContentRevision implements ContentRevision, MarkerVcsContentRevi
@Nullable
public String getContent() throws VcsException {
return ContentRevisionCache.getAsString(getContentAsBytes(), myFile, null);
}
@Nullable
@Override
public byte[] getContentAsBytes() throws VcsException {
try {
if (myUseBaseRevision) {
return ContentRevisionCache.getOrLoadCurrentAsString(myVcs.getProject(), myFile, myVcs.getKeyInstanceMethod(),
new CurrentRevisionProvider() {
@Override
public VcsRevisionNumber getCurrentRevision() throws VcsException {
return getRevisionNumber();
}
return ContentRevisionCache.getOrLoadCurrentAsBytes(myVcs.getProject(), myFile, myVcs.getKeyInstanceMethod(),
new CurrentRevisionProvider() {
@Override
public VcsRevisionNumber getCurrentRevision() throws VcsException {
return getRevisionNumber();
}
@Override
public Pair<VcsRevisionNumber, byte[]> get()
throws VcsException, IOException {
return Pair.create(getRevisionNumber(), getUpToDateBinaryContent());
}
}).getSecond();
@Override
public Pair<VcsRevisionNumber, byte[]> get()
throws VcsException, IOException {
return Pair.create(getRevisionNumber(), getUpToDateBinaryContent());
}
}).getSecond();
} else {
return ContentRevisionCache.getOrLoadAsString(myVcs.getProject(), myFile, getRevisionNumber(), myVcs.getKeyInstanceMethod(),
ContentRevisionCache.UniqueType.REPOSITORY_CONTENT,
new Throwable2Computable<byte[], VcsException, IOException>() {
@Override
public byte[] compute() throws VcsException, IOException {
return getUpToDateBinaryContent();
}
});
return ContentRevisionCache.getOrLoadAsBytes(myVcs.getProject(), myFile, getRevisionNumber(), myVcs.getKeyInstanceMethod(),
ContentRevisionCache.UniqueType.REPOSITORY_CONTENT,
new Throwable2Computable<byte[], VcsException, IOException>() {
@Override
public byte[] compute() throws VcsException, IOException {
return getUpToDateBinaryContent();
}
});
}
}
catch (IOException e) {
@@ -112,7 +118,7 @@ public class SvnContentRevision implements ContentRevision, MarkerVcsContentRevi
}
}
protected byte[] getUpToDateBinaryContent() throws VcsException {
private byte[] getUpToDateBinaryContent() throws VcsException {
File file = myFile.getIOFile();
File lock = new File(file.getParentFile(), SvnUtil.PATH_TO_LOCK_FILE);
if (lock.exists()) {
@@ -18,21 +18,20 @@ package org.jetbrains.idea.svn.diff;
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.changes.ByteBackedContentRevision;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.io.SVNRepository;
import java.nio.charset.Charset;
public class DiffContentRevision implements ContentRevision {
public class DiffContentRevision implements ByteBackedContentRevision {
private String myPath;
private SVNRepository myRepository;
private String myContents;
private byte[] myContents;
private FilePath myFilePath;
private long myRevision;
@@ -47,19 +46,26 @@ public class DiffContentRevision implements ContentRevision {
myRevision = revision;
}
@Nullable
@NotNull
public String getContent() throws VcsException {
final byte[] bytes = getContentAsBytes();
final Charset charset = myFilePath.getCharset();
return CharsetToolkit.bytesToString(bytes, charset);
}
@NotNull
@Override
public byte[] getContentAsBytes() throws VcsException {
if (myContents == null) {
BufferExposingByteArrayOutputStream bos = new BufferExposingByteArrayOutputStream(2048);
try {
myRepository.getFile(myPath, -1, null, bos);
myRepository.closeSession();
} catch (SVNException e) {
}
catch (SVNException e) {
throw new VcsException(e);
}
final byte[] bytes = bos.toByteArray();
final Charset charset = myFilePath.getCharset();
myContents = CharsetToolkit.bytesToString(bytes, charset);
myContents = bos.toByteArray();
}
return myContents;
}
@@ -30,7 +30,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.changes.ByteBackedContentRevision;
import com.intellij.openapi.vcs.changes.MarkerVcsContentRevision;
import com.intellij.openapi.vcs.impl.ContentRevisionCache;
import com.intellij.openapi.vfs.LocalFileSystem;
@@ -49,7 +49,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class SvnRepositoryContentRevision implements ContentRevision, MarkerVcsContentRevision {
public class SvnRepositoryContentRevision implements ByteBackedContentRevision, MarkerVcsContentRevision {
@NotNull private final SvnVcs myVcs;
@NotNull private final String myPath;
@@ -63,20 +63,26 @@ public class SvnRepositoryContentRevision implements ContentRevision, MarkerVcsC
myRevision = revision;
}
@Nullable
@NotNull
public String getContent() throws VcsException {
return ContentRevisionCache.getAsString(getContentAsBytes(), myFilePath, null);
}
@NotNull
@Override
public byte[] getContentAsBytes() throws VcsException {
try {
if (myFilePath.getVirtualFile() == null) {
LocalFileSystem.getInstance().refreshAndFindFileByPath(myFilePath.getPath());
}
return ContentRevisionCache.getOrLoadAsString(myVcs.getProject(), myFilePath, getRevisionNumber(), myVcs.getKeyInstanceMethod(),
ContentRevisionCache.UniqueType.REPOSITORY_CONTENT,
new Throwable2Computable<byte[], VcsException, IOException>() {
@Override
public byte[] compute() throws VcsException, IOException {
return loadContent().toByteArray();
}
});
return ContentRevisionCache.getOrLoadAsBytes(myVcs.getProject(), myFilePath, getRevisionNumber(), myVcs.getKeyInstanceMethod(),
ContentRevisionCache.UniqueType.REPOSITORY_CONTENT,
new Throwable2Computable<byte[], VcsException, IOException>() {
@Override
public byte[] compute() throws VcsException, IOException {
return loadContent().toByteArray();
}
});
}
catch (IOException e) {
throw new VcsException(e);