svn: Renamed "AbstractShowPropertiesDiffAction" to "ShowPropertiesDiffAction"
[idea/community.git] / plugins / svn4idea / src / org / jetbrains / idea / svn / history / SvnRepositoryContentRevision.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 /*
18  * Created by IntelliJ IDEA.
19  * User: yole
20  * Date: 28.11.2006
21  * Time: 17:48:18
22  */
23 package org.jetbrains.idea.svn.history;
24
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;
43
44 import java.io.ByteArrayOutputStream;
45 import java.io.IOException;
46 import java.io.OutputStream;
47
48 import static com.intellij.util.ObjectUtils.notNull;
49
50 public class SvnRepositoryContentRevision extends SvnBaseContentRevision implements ByteBackedContentRevision, MarkerVcsContentRevision {
51
52   @NotNull private final String myPath;
53   private final long myRevision;
54
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;
59   }
60
61   @NotNull
62   public String getContent() throws VcsException {
63     return ContentRevisionCache.getAsString(getContentAsBytes(), myFile, null);
64   }
65
66   @NotNull
67   @Override
68   public byte[] getContentAsBytes() throws VcsException {
69     try {
70       if (myFile.getVirtualFile() == null) {
71         LocalFileSystem.getInstance().refreshAndFindFileByPath(myFile.getPath());
72       }
73       return ContentRevisionCache.getOrLoadAsBytes(myVcs.getProject(), myFile, getRevisionNumber(), myVcs.getKeyInstanceMethod(),
74                                                    ContentRevisionCache.UniqueType.REPOSITORY_CONTENT, () -> loadContent().toByteArray());
75     }
76     catch (IOException e) {
77       throw new VcsException(e);
78     }
79   }
80
81   @NotNull
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);
88     }
89     else {
90       loader.run();
91     }
92     final Exception exception = loader.getException();
93     if (exception != null) {
94       throw new VcsException(exception);
95     }
96     ContentRevisionCache.checkContentsSize(myPath, buffer.size());
97     return buffer;
98   }
99
100   @NotNull
101   public SvnRevisionNumber getRevisionNumber() {
102     return new SvnRevisionNumber(SVNRevision.create(myRevision));
103   }
104
105   public static SvnRepositoryContentRevision create(@NotNull SvnVcs vcs,
106                                                     @NotNull String repositoryRoot,
107                                                     @NotNull String path,
108                                                     @Nullable FilePath localPath,
109                                                     long revision) {
110     return create(vcs, SvnUtil.appendMultiParts(repositoryRoot, path), localPath, revision);
111   }
112
113   public static SvnRepositoryContentRevision createForRemotePath(@NotNull SvnVcs vcs,
114                                                                  @NotNull String repositoryRoot,
115                                                                  @NotNull String path,
116                                                                  boolean isDirectory,
117                                                                  long revision) {
118     FilePath remotePath = VcsUtil.getFilePathOnNonLocal(SvnUtil.appendMultiParts(repositoryRoot, path), isDirectory);
119     return create(vcs, remotePath, remotePath, revision);
120   }
121
122   public static SvnRepositoryContentRevision create(@NotNull SvnVcs vcs,
123                                                     @NotNull String fullPath,
124                                                     @Nullable FilePath localPath,
125                                                     long revision) {
126     // TODO: Check if isDirectory = false always true for this method calls
127     FilePath remotePath = VcsUtil.getFilePathOnNonLocal(fullPath, false);
128
129     return create(vcs, remotePath, localPath == null ? remotePath : localPath, revision);
130   }
131
132   public static SvnRepositoryContentRevision create(@NotNull SvnVcs vcs,
133                                                     @NotNull FilePath remotePath,
134                                                     @Nullable FilePath localPath,
135                                                     long revision) {
136     return remotePath.getFileType().isBinary()
137            ? new SvnRepositoryBinaryContentRevision(vcs, remotePath, localPath, revision)
138            : new SvnRepositoryContentRevision(vcs, remotePath, localPath, revision);
139   }
140
141   @Override
142   public String toString() {
143     return myFile.getIOFile() + "#" + myRevision;
144   }
145
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;
151
152     public ContentLoader(String path, OutputStream dst, long revision) {
153       myPath = path;
154       myDst = dst;
155       myRevision = revision;
156     }
157
158     public Exception getException() {
159       return myException;
160     }
161
162     public void run() {
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));
167       }
168
169       try {
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);
174       }
175       catch (VcsException e) {
176         myException = e;
177       }
178       catch (IOException e) {
179         myException = e;
180       }
181     }
182   }
183
184   @NotNull
185   public String getFullPath() {
186     return myPath;
187   }
188
189   public String getRelativePath(@NotNull String repositoryUrl) {
190     return SvnUtil.getRelativePath(repositoryUrl, myPath);
191   }
192
193   @Override
194   public VcsKey getVcsKey() {
195     return SvnVcs.getKey();
196   }
197
198   @NotNull
199   public SvnTarget toTarget() throws SvnBindException {
200     return SvnTarget.fromURL(SvnUtil.createUrl(getFullPath()), getRevisionNumber().getRevision());
201   }
202 }