2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * Created by IntelliJ IDEA.
23 package org.jetbrains.idea.svn.history;
25 import com.intellij.openapi.application.ApplicationManager;
26 import com.intellij.openapi.progress.ProgressIndicator;
27 import com.intellij.openapi.progress.ProgressManager;
28 import com.intellij.openapi.util.io.FileUtil;
29 import com.intellij.openapi.vcs.FilePath;
30 import com.intellij.openapi.vcs.VcsException;
31 import com.intellij.openapi.vcs.VcsKey;
32 import com.intellij.openapi.vcs.changes.ByteBackedContentRevision;
33 import com.intellij.openapi.vcs.changes.MarkerVcsContentRevision;
34 import com.intellij.openapi.vcs.impl.ContentRevisionCache;
35 import com.intellij.openapi.vfs.LocalFileSystem;
36 import com.intellij.vcsUtil.VcsUtil;
37 import org.jetbrains.annotations.NotNull;
38 import org.jetbrains.annotations.Nullable;
39 import org.jetbrains.idea.svn.*;
40 import org.jetbrains.idea.svn.commandLine.SvnBindException;
41 import org.tmatesoft.svn.core.wc.SVNRevision;
42 import org.tmatesoft.svn.core.wc2.SvnTarget;
44 import java.io.ByteArrayOutputStream;
45 import java.io.IOException;
46 import java.io.OutputStream;
48 import static com.intellij.util.ObjectUtils.notNull;
50 public class SvnRepositoryContentRevision extends SvnBaseContentRevision implements ByteBackedContentRevision, MarkerVcsContentRevision {
52 @NotNull private final String myPath;
53 private final long myRevision;
55 public SvnRepositoryContentRevision(@NotNull SvnVcs vcs, @NotNull FilePath remotePath, @Nullable FilePath localPath, long revision) {
56 super(vcs, notNull(localPath, remotePath));
57 myPath = FileUtil.toSystemIndependentName(remotePath.getPath());
58 myRevision = revision;
62 public String getContent() throws VcsException {
63 return ContentRevisionCache.getAsString(getContentAsBytes(), myFile, null);
68 public byte[] getContentAsBytes() throws VcsException {
70 if (myFile.getVirtualFile() == null) {
71 LocalFileSystem.getInstance().refreshAndFindFileByPath(myFile.getPath());
73 return ContentRevisionCache.getOrLoadAsBytes(myVcs.getProject(), myFile, getRevisionNumber(), myVcs.getKeyInstanceMethod(),
74 ContentRevisionCache.UniqueType.REPOSITORY_CONTENT, () -> loadContent().toByteArray());
76 catch (IOException e) {
77 throw new VcsException(e);
82 protected ByteArrayOutputStream loadContent() throws VcsException {
83 final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
84 ContentLoader loader = new ContentLoader(myPath, buffer, myRevision);
85 if (ApplicationManager.getApplication().isDispatchThread()) {
86 ProgressManager.getInstance()
87 .runProcessWithProgressSynchronously(loader, SvnBundle.message("progress.title.loading.file.content"), false, null);
92 final Exception exception = loader.getException();
93 if (exception != null) {
94 throw new VcsException(exception);
96 ContentRevisionCache.checkContentsSize(myPath, buffer.size());
101 public SvnRevisionNumber getRevisionNumber() {
102 return new SvnRevisionNumber(SVNRevision.create(myRevision));
105 public static SvnRepositoryContentRevision create(@NotNull SvnVcs vcs,
106 @NotNull String repositoryRoot,
107 @NotNull String path,
108 @Nullable FilePath localPath,
110 return create(vcs, SvnUtil.appendMultiParts(repositoryRoot, path), localPath, revision);
113 public static SvnRepositoryContentRevision createForRemotePath(@NotNull SvnVcs vcs,
114 @NotNull String repositoryRoot,
115 @NotNull String path,
118 FilePath remotePath = VcsUtil.getFilePathOnNonLocal(SvnUtil.appendMultiParts(repositoryRoot, path), isDirectory);
119 return create(vcs, remotePath, remotePath, revision);
122 public static SvnRepositoryContentRevision create(@NotNull SvnVcs vcs,
123 @NotNull String fullPath,
124 @Nullable FilePath localPath,
126 // TODO: Check if isDirectory = false always true for this method calls
127 FilePath remotePath = VcsUtil.getFilePathOnNonLocal(fullPath, false);
129 return create(vcs, remotePath, localPath == null ? remotePath : localPath, revision);
132 public static SvnRepositoryContentRevision create(@NotNull SvnVcs vcs,
133 @NotNull FilePath remotePath,
134 @Nullable FilePath localPath,
136 return remotePath.getFileType().isBinary()
137 ? new SvnRepositoryBinaryContentRevision(vcs, remotePath, localPath, revision)
138 : new SvnRepositoryContentRevision(vcs, remotePath, localPath, revision);
142 public String toString() {
143 return myFile.getIOFile() + "#" + myRevision;
146 private class ContentLoader implements Runnable {
147 private final String myPath;
148 private final long myRevision;
149 private final OutputStream myDst;
150 private Exception myException;
152 public ContentLoader(String path, OutputStream dst, long revision) {
155 myRevision = revision;
158 public Exception getException() {
163 ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
164 if (progress != null) {
165 progress.setText(SvnBundle.message("progress.text.loading.contents", myPath));
166 progress.setText2(SvnBundle.message("progress.text2.revision.information", myRevision));
170 // TODO: Local path could also be used here
171 SVNRevision revision = SVNRevision.create(myRevision);
172 byte[] contents = SvnUtil.getFileContents(myVcs, SvnTarget.fromURL(SvnUtil.parseUrl(getFullPath())), revision, revision);
173 myDst.write(contents);
175 catch (VcsException e) {
178 catch (IOException e) {
185 public String getFullPath() {
189 public String getRelativePath(@NotNull String repositoryUrl) {
190 return SvnUtil.getRelativePath(repositoryUrl, myPath);
194 public VcsKey getVcsKey() {
195 return SvnVcs.getKey();
199 public SvnTarget toTarget() throws SvnBindException {
200 return SvnTarget.fromURL(SvnUtil.createUrl(getFullPath()), getRevisionNumber().getRevision());