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 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
;
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() {
64 public String
getAfterPath() {
69 public String
getAfterFileName() {
70 if (myAfterPath
== null) return null;
71 int pos
= myAfterPath
.lastIndexOf('/');
72 if (pos
>= 0) return myAfterPath
.substring(pos
+1);
76 public String
getBeforeFileName() {
77 int pos
= myBeforePath
.lastIndexOf('/');
78 if (pos
>= 0) return myBeforePath
.substring(pos
+1);
82 public String
getBeforeDirectory() {
83 int pos
= myBeforePath
.lastIndexOf('/');
84 if (pos
>= 0) return myBeforePath
.substring(0, pos
).replace('/', File
.separatorChar
);
85 return File
.separator
;
88 public FileStatus
getFileStatus() {
92 public Change
getChange(Project project
) {
93 if (myChange
== null) {
94 ContentRevision beforeRevision
= null;
95 ContentRevision afterRevision
= null;
96 File baseDir
= new File(project
.getBaseDir().getPath());
98 File file
= getAbsolutePath(baseDir
, myBeforePath
);
99 final FilePathImpl beforePath
= new FilePathImpl(file
, false);
100 beforePath
.refresh();
101 if (myFileStatus
!= FileStatus
.ADDED
) {
102 beforeRevision
= new CurrentContentRevision(beforePath
) {
104 public VcsRevisionNumber
getRevisionNumber() {
105 return new TextRevisionNumber(VcsBundle
.message("local.version.title"));
109 if (myFileStatus
!= FileStatus
.DELETED
) {
110 final FilePathImpl afterPath
= new FilePathImpl(getAbsolutePath(baseDir
, myAfterPath
), false);
111 afterRevision
= new PatchedContentRevision(beforePath
, afterPath
);
113 myChange
= new Change(beforeRevision
, afterRevision
, myFileStatus
);
118 private static File
getAbsolutePath(final File baseDir
, final String relativePath
) {
121 file
= new File(baseDir
, relativePath
).getCanonicalFile();
123 catch (IOException e
) {
125 file
= new File(baseDir
, relativePath
);
131 public TextFilePatch
loadFilePatch() throws IOException
, PatchSyntaxException
{
132 List
<TextFilePatch
> filePatches
= ShelveChangesManager
.loadPatches(myPatchPath
);
133 for(TextFilePatch patch
: filePatches
) {
134 if (myBeforePath
.equals(patch
.getBeforeName())) {
142 public boolean equals(final Object o
) {
143 if (this == o
) return true;
144 if (!(o
instanceof ShelvedChange
)) return false;
146 final ShelvedChange that
= (ShelvedChange
)o
;
148 if (myAfterPath
!= null ?
!myAfterPath
.equals(that
.myAfterPath
) : that
.myAfterPath
!= null) return false;
149 if (myBeforePath
!= null ?
!myBeforePath
.equals(that
.myBeforePath
) : that
.myBeforePath
!= null) return false;
150 if (myFileStatus
!= null ?
!myFileStatus
.equals(that
.myFileStatus
) : that
.myFileStatus
!= null) return false;
151 if (myPatchPath
!= null ?
!myPatchPath
.equals(that
.myPatchPath
) : that
.myPatchPath
!= null) return false;
157 public int hashCode() {
158 int result
= myPatchPath
!= null ? myPatchPath
.hashCode() : 0;
159 result
= 31 * result
+ (myBeforePath
!= null ? myBeforePath
.hashCode() : 0);
160 result
= 31 * result
+ (myAfterPath
!= null ? myAfterPath
.hashCode() : 0);
161 result
= 31 * result
+ (myFileStatus
!= null ? myFileStatus
.hashCode() : 0);
165 private class PatchedContentRevision
implements ContentRevision
{
166 private final FilePath myBeforeFilePath
;
167 private final FilePath myAfterFilePath
;
168 private String myContent
;
170 public PatchedContentRevision(final FilePath beforeFilePath
, final FilePath afterFilePath
) {
171 myBeforeFilePath
= beforeFilePath
;
172 myAfterFilePath
= afterFilePath
;
176 public String
getContent() throws VcsException
{
177 if (myContent
== null) {
179 myContent
= loadContent();
181 catch (Exception e
) {
182 throw new VcsException(e
);
190 private String
loadContent() throws IOException
, PatchSyntaxException
, ApplyPatchException
{
191 TextFilePatch patch
= loadFilePatch();
193 return loadContent(patch
);
198 private String
loadContent(final TextFilePatch patch
) throws ApplyPatchException
{
199 if (patch
.isNewFile()) {
200 return patch
.getNewFileText();
202 if (patch
.isDeletedFile()) {
205 StringBuilder newText
= new StringBuilder();
206 patch
.applyModifications(getBaseContent(), newText
);
207 return newText
.toString();
210 private String
getBaseContent() {
211 myBeforeFilePath
.refresh();
212 final Document doc
= FileDocumentManager
.getInstance().getDocument(myBeforeFilePath
.getVirtualFile());
213 return doc
.getText();
217 public FilePath
getFile() {
218 return myAfterFilePath
;
222 public VcsRevisionNumber
getRevisionNumber() {
223 return new TextRevisionNumber(VcsBundle
.message("shelved.version.name"));
227 private static class TextRevisionNumber
implements VcsRevisionNumber
{
228 private final String myText
;
230 public TextRevisionNumber(final String text
) {
234 public String
asString() {
238 public int compareTo(final VcsRevisionNumber o
) {
243 public String
getPatchPath() {