08420362524333bb191987ef861f6af3fa71bc1b
[idea/community.git] / plugins / svn4idea / src / org / jetbrains / idea / svn / SvnContentRevision.java
1 /*
2  * Copyright 2000-2014 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 package org.jetbrains.idea.svn;
18
19 import com.intellij.openapi.util.Pair;
20 import com.intellij.openapi.vcs.FilePath;
21 import com.intellij.openapi.vcs.VcsException;
22 import com.intellij.openapi.vcs.VcsKey;
23 import com.intellij.openapi.vcs.changes.ByteBackedContentRevision;
24 import com.intellij.openapi.vcs.changes.MarkerVcsContentRevision;
25 import com.intellij.openapi.vcs.history.VcsRevisionNumber;
26 import com.intellij.openapi.vcs.impl.ContentRevisionCache;
27 import com.intellij.openapi.vcs.impl.CurrentRevisionProvider;
28 import org.jetbrains.annotations.NonNls;
29 import org.jetbrains.annotations.NotNull;
30 import org.jetbrains.annotations.Nullable;
31 import org.jetbrains.idea.svn.status.Status;
32 import org.tmatesoft.svn.core.wc.SVNRevision;
33 import org.tmatesoft.svn.core.wc2.SvnTarget;
34
35 import java.io.File;
36 import java.io.IOException;
37
38 public class SvnContentRevision extends SvnBaseContentRevision implements ByteBackedContentRevision, MarkerVcsContentRevision {
39
40   @NotNull private final SVNRevision myRevision;
41   /**
42    * this flag is necessary since SVN would not do remote request only if constant SVNRevision.BASE
43    * -> usual current revision content class can't be used
44    */
45   private final boolean myUseBaseRevision;
46
47   protected SvnContentRevision(@NotNull SvnVcs vcs, @NotNull FilePath file, @NotNull SVNRevision revision, boolean useBaseRevision) {
48     super(vcs, file);
49     myRevision = revision;
50     myUseBaseRevision = useBaseRevision;
51   }
52
53   @NotNull
54   public static SvnContentRevision createBaseRevision(@NotNull SvnVcs vcs, @NotNull FilePath file, @NotNull Status status) {
55     SVNRevision revision = status.getRevision().isValid() ? status.getRevision() : status.getCommittedRevision();
56     return createBaseRevision(vcs, file, revision);
57   }
58
59   @NotNull
60   public static SvnContentRevision createBaseRevision(@NotNull SvnVcs vcs, @NotNull FilePath file, @NotNull SVNRevision revision) {
61     if (file.getFileType().isBinary()) {
62       return new SvnBinaryContentRevision(vcs, file, revision, true);
63     }
64     return new SvnContentRevision(vcs, file, revision, true);
65   }
66
67   @NotNull
68   public static SvnContentRevision createRemote(@NotNull SvnVcs vcs, @NotNull FilePath file, @NotNull SVNRevision revision) {
69     if (file.getFileType().isBinary()) {
70       return new SvnBinaryContentRevision(vcs, file, revision, false);
71     }
72     return new SvnContentRevision(vcs, file, revision, false);
73   }
74
75   @Nullable
76   public String getContent() throws VcsException {
77     return ContentRevisionCache.getAsString(getContentAsBytes(), myFile, null);
78   }
79
80   @Nullable
81   @Override
82   public byte[] getContentAsBytes() throws VcsException {
83     try {
84       if (myUseBaseRevision) {
85         return ContentRevisionCache.getOrLoadCurrentAsBytes(myVcs.getProject(), myFile, myVcs.getKeyInstanceMethod(),
86                                                             new CurrentRevisionProvider() {
87                                                               @Override
88                                                               public VcsRevisionNumber getCurrentRevision() throws VcsException {
89                                                                 return getRevisionNumber();
90                                                               }
91
92                                                               @Override
93                                                               public Pair<VcsRevisionNumber, byte[]> get()
94                                                                 throws VcsException, IOException {
95                                                                 return Pair.create(getRevisionNumber(), getUpToDateBinaryContent());
96                                                               }
97                                                             }).getSecond();
98       } else {
99         return ContentRevisionCache.getOrLoadAsBytes(myVcs.getProject(), myFile, getRevisionNumber(), myVcs.getKeyInstanceMethod(),
100                                                      ContentRevisionCache.UniqueType.REPOSITORY_CONTENT, () -> getUpToDateBinaryContent());
101       }
102     }
103     catch (IOException e) {
104       throw new VcsException(e);
105     }
106   }
107
108   private byte[] getUpToDateBinaryContent() throws VcsException {
109     File file = myFile.getIOFile();
110     File lock = new File(file.getParentFile(), SvnUtil.PATH_TO_LOCK_FILE);
111     if (lock.exists()) {
112       throw new VcsException("Can not access file base revision contents: administrative area is locked");
113     }
114     return SvnUtil.getFileContents(myVcs, SvnTarget.fromFile(file), myUseBaseRevision ? SVNRevision.BASE : myRevision,
115                                    SVNRevision.UNDEFINED);
116   }
117
118   @NotNull
119   public VcsRevisionNumber getRevisionNumber() {
120     return new SvnRevisionNumber(myRevision);
121   }
122
123   @NonNls
124   public String toString() {
125     return myFile.getPath();
126   }
127
128   @Override
129   public VcsKey getVcsKey() {
130     return SvnVcs.getKey();
131   }
132 }