VCS: shelved changes: navigatable show diff: allow conflicting changes to be shown...
[fedora-idea.git] / platform / vcs-impl / src / com / intellij / openapi / vcs / changes / shelf / ShelvedChange.java
blobeabdd4733b46e06868f9b78ae7c710664a3fa6cd
1 /*
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.
19 * User: yole
20 * Date: 23.11.2006
21 * Time: 19:06:26
23 package com.intellij.openapi.vcs.changes.shelf;
25 import com.intellij.openapi.diagnostic.Logger;
26 import com.intellij.openapi.diff.impl.patch.ApplyPatchException;
27 import com.intellij.openapi.diff.impl.patch.PatchSyntaxException;
28 import com.intellij.openapi.diff.impl.patch.TextFilePatch;
29 import com.intellij.openapi.editor.Document;
30 import com.intellij.openapi.fileEditor.FileDocumentManager;
31 import com.intellij.openapi.project.Project;
32 import com.intellij.openapi.vcs.*;
33 import com.intellij.openapi.vcs.changes.Change;
34 import com.intellij.openapi.vcs.changes.ContentRevision;
35 import com.intellij.openapi.vcs.changes.CurrentContentRevision;
36 import com.intellij.openapi.vcs.history.VcsRevisionNumber;
37 import org.jetbrains.annotations.NotNull;
38 import org.jetbrains.annotations.Nullable;
40 import java.io.File;
41 import java.io.IOException;
42 import java.util.List;
44 public class ShelvedChange {
45 private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.shelf.ShelvedChange");
47 private final String myPatchPath;
48 private final String myBeforePath;
49 private final String myAfterPath;
50 private final FileStatus myFileStatus;
51 private Change myChange;
53 public ShelvedChange(final String patchPath, final String beforePath, final String afterPath, final FileStatus fileStatus) {
54 myPatchPath = patchPath;
55 myBeforePath = beforePath;
56 myAfterPath = afterPath;
57 myFileStatus = fileStatus;
60 public String getBeforePath() {
61 return myBeforePath;
64 public String getAfterPath() {
65 return myAfterPath;
68 public String getBeforeFileName() {
69 int pos = myBeforePath.lastIndexOf('/');
70 if (pos >= 0) return myBeforePath.substring(pos+1);
71 return myBeforePath;
74 public String getBeforeDirectory() {
75 int pos = myBeforePath.lastIndexOf('/');
76 if (pos >= 0) return myBeforePath.substring(0, pos).replace('/', File.separatorChar);
77 return File.separator;
80 public FileStatus getFileStatus() {
81 return myFileStatus;
84 public Change getChange(Project project) {
85 if (myChange == null) {
86 ContentRevision beforeRevision = null;
87 ContentRevision afterRevision = null;
88 File baseDir = new File(project.getBaseDir().getPath());
90 File file = getAbsolutePath(baseDir, myBeforePath);
91 final FilePathImpl beforePath = new FilePathImpl(file, false);
92 beforePath.refresh();
93 if (myFileStatus != FileStatus.ADDED) {
94 beforeRevision = new CurrentContentRevision(beforePath) {
95 @NotNull
96 public VcsRevisionNumber getRevisionNumber() {
97 return new TextRevisionNumber(VcsBundle.message("local.version.title"));
101 if (myFileStatus != FileStatus.DELETED) {
102 final FilePathImpl afterPath = new FilePathImpl(getAbsolutePath(baseDir, myAfterPath), false);
103 afterRevision = new PatchedContentRevision(beforePath, afterPath);
105 myChange = new Change(beforeRevision, afterRevision, myFileStatus);
107 return myChange;
110 private static File getAbsolutePath(final File baseDir, final String relativePath) {
111 File file;
112 try {
113 file = new File(baseDir, relativePath).getCanonicalFile();
115 catch (IOException e) {
116 LOG.info(e);
117 file = new File(baseDir, relativePath);
119 return file;
122 @Nullable
123 public TextFilePatch loadFilePatch() throws IOException, PatchSyntaxException {
124 List<TextFilePatch> filePatches = ShelveChangesManager.loadPatches(myPatchPath);
125 for(TextFilePatch patch: filePatches) {
126 if (myBeforePath.equals(patch.getBeforeName())) {
127 return patch;
130 return null;
133 @Override
134 public boolean equals(final Object o) {
135 if (this == o) return true;
136 if (!(o instanceof ShelvedChange)) return false;
138 final ShelvedChange that = (ShelvedChange)o;
140 if (myAfterPath != null ? !myAfterPath.equals(that.myAfterPath) : that.myAfterPath != null) return false;
141 if (myBeforePath != null ? !myBeforePath.equals(that.myBeforePath) : that.myBeforePath != null) return false;
142 if (myFileStatus != null ? !myFileStatus.equals(that.myFileStatus) : that.myFileStatus != null) return false;
143 if (myPatchPath != null ? !myPatchPath.equals(that.myPatchPath) : that.myPatchPath != null) return false;
145 return true;
148 @Override
149 public int hashCode() {
150 int result = myPatchPath != null ? myPatchPath.hashCode() : 0;
151 result = 31 * result + (myBeforePath != null ? myBeforePath.hashCode() : 0);
152 result = 31 * result + (myAfterPath != null ? myAfterPath.hashCode() : 0);
153 result = 31 * result + (myFileStatus != null ? myFileStatus.hashCode() : 0);
154 return result;
157 private class PatchedContentRevision implements ContentRevision {
158 private final FilePath myBeforeFilePath;
159 private final FilePath myAfterFilePath;
160 private String myContent;
162 public PatchedContentRevision(final FilePath beforeFilePath, final FilePath afterFilePath) {
163 myBeforeFilePath = beforeFilePath;
164 myAfterFilePath = afterFilePath;
167 @Nullable
168 public String getContent() throws VcsException {
169 if (myContent == null) {
170 try {
171 myContent = loadContent();
173 catch (Exception e) {
174 throw new VcsException(e);
178 return myContent;
181 @Nullable
182 private String loadContent() throws IOException, PatchSyntaxException, ApplyPatchException {
183 TextFilePatch patch = loadFilePatch();
184 if (patch != null) {
185 return loadContent(patch);
187 return null;
190 private String loadContent(final TextFilePatch patch) throws ApplyPatchException {
191 if (patch.isNewFile()) {
192 return patch.getNewFileText();
194 if (patch.isDeletedFile()) {
195 return null;
197 StringBuilder newText = new StringBuilder();
198 patch.applyModifications(getBaseContent(), newText);
199 return newText.toString();
202 private String getBaseContent() {
203 myBeforeFilePath.refresh();
204 final Document doc = FileDocumentManager.getInstance().getDocument(myBeforeFilePath.getVirtualFile());
205 return doc.getText();
208 @NotNull
209 public FilePath getFile() {
210 return myAfterFilePath;
213 @NotNull
214 public VcsRevisionNumber getRevisionNumber() {
215 return new TextRevisionNumber(VcsBundle.message("shelved.version.name"));
219 private static class TextRevisionNumber implements VcsRevisionNumber {
220 private final String myText;
222 public TextRevisionNumber(final String text) {
223 myText = text;
226 public String asString() {
227 return myText;
230 public int compareTo(final VcsRevisionNumber o) {
231 return 0;
235 public String getPatchPath() {
236 return myPatchPath;