IDEA-25809 (9.0 Beta 1 CVS support flaky)
[fedora-idea.git] / plugins / cvs / cvs-plugin / src / com / intellij / cvsSupport2 / CvsDiffProvider.java
blob12b1046f6196d7f9c098ba0fe33063829d4dd269
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.
16 package com.intellij.cvsSupport2;
18 import com.intellij.CvsBundle;
19 import com.intellij.cvsSupport2.application.CvsEntriesManager;
20 import com.intellij.cvsSupport2.changeBrowser.CvsBinaryContentRevision;
21 import com.intellij.cvsSupport2.changeBrowser.CvsContentRevision;
22 import com.intellij.cvsSupport2.connections.CvsConnectionSettings;
23 import com.intellij.cvsSupport2.connections.CvsRootProvider;
24 import com.intellij.cvsSupport2.cvsExecution.CvsOperationExecutor;
25 import com.intellij.cvsSupport2.cvsExecution.CvsOperationExecutorCallback;
26 import com.intellij.cvsSupport2.cvsExecution.ModalityContext;
27 import com.intellij.cvsSupport2.cvsExecution.ModalityContextImpl;
28 import com.intellij.cvsSupport2.cvshandlers.CommandCvsHandler;
29 import com.intellij.cvsSupport2.cvsoperations.common.CvsExecutionEnvironment;
30 import com.intellij.cvsSupport2.cvsoperations.common.PostCvsActivity;
31 import com.intellij.cvsSupport2.cvsoperations.cvsErrors.ErrorProcessor;
32 import com.intellij.cvsSupport2.cvsoperations.cvsLog.LogOperation;
33 import com.intellij.cvsSupport2.cvsoperations.cvsMessages.CvsMessagesAdapter;
34 import com.intellij.cvsSupport2.cvsoperations.cvsStatus.StatusOperation;
35 import com.intellij.cvsSupport2.cvsoperations.dateOrRevision.RevisionOrDate;
36 import com.intellij.cvsSupport2.cvsoperations.dateOrRevision.RevisionOrDateImpl;
37 import com.intellij.cvsSupport2.cvsoperations.dateOrRevision.SimpleRevision;
38 import com.intellij.cvsSupport2.history.CvsRevisionNumber;
39 import com.intellij.cvsSupport2.util.CvsVfsUtil;
40 import com.intellij.openapi.project.Project;
41 import com.intellij.openapi.util.Ref;
42 import com.intellij.openapi.vcs.FilePath;
43 import com.intellij.openapi.vcs.FilePathImpl;
44 import com.intellij.openapi.vcs.VcsException;
45 import com.intellij.openapi.vcs.changes.ContentRevision;
46 import com.intellij.openapi.vcs.diff.DiffProvider;
47 import com.intellij.openapi.vcs.diff.ItemLatestState;
48 import com.intellij.openapi.vcs.history.VcsRevisionNumber;
49 import com.intellij.openapi.vfs.LocalFileSystem;
50 import com.intellij.openapi.vfs.VirtualFile;
51 import org.jetbrains.annotations.Nullable;
52 import org.netbeans.lib.cvsclient.admin.Entry;
53 import org.netbeans.lib.cvsclient.command.Command;
54 import org.netbeans.lib.cvsclient.command.CommandAbortedException;
55 import org.netbeans.lib.cvsclient.command.log.LogCommand;
56 import org.netbeans.lib.cvsclient.command.log.LogInformation;
57 import org.netbeans.lib.cvsclient.command.status.StatusCommand;
58 import org.netbeans.lib.cvsclient.file.FileStatus;
60 import java.io.File;
61 import java.util.Collections;
62 import java.util.List;
64 public class CvsDiffProvider implements DiffProvider{
65 private final Project myProject;
67 public CvsDiffProvider(final Project project) {
68 myProject = project;
71 public VcsRevisionNumber getCurrentRevision(VirtualFile file) {
72 final Entry entry = CvsEntriesManager.getInstance().getEntryFor(file);
73 if (entry == null) return null;
74 return new CvsRevisionNumber(entry.getRevision());
77 public ItemLatestState getLastRevision(VirtualFile virtualFile) {
78 //return getLastRevision(CvsVfsUtil.getFileFor(virtualFile));
79 if (virtualFile.getParent() == null) {
80 return new ItemLatestState(new CvsRevisionNumber("HEAD"), true);
82 return getLastState(virtualFile.getParent(), virtualFile.getName());
85 public ContentRevision createFileContent(final VcsRevisionNumber revisionNumber, VirtualFile selectedFile) {
86 if ((revisionNumber instanceof CvsRevisionNumber)) {
87 final CvsConnectionSettings settings = CvsEntriesManager.getInstance().getCvsConnectionSettingsFor(selectedFile.getParent());
88 final File file = new File(CvsUtil.getModuleName(selectedFile));
89 final CvsRevisionNumber cvsRevisionNumber = ((CvsRevisionNumber)revisionNumber);
90 final RevisionOrDate versionInfo;
91 if (cvsRevisionNumber.getDateOrRevision() != null) {
92 versionInfo = RevisionOrDateImpl.createOn(cvsRevisionNumber.getDateOrRevision());
94 else {
95 versionInfo = new SimpleRevision(cvsRevisionNumber.asString());
98 if (selectedFile.getFileType().isBinary()) {
99 return new CvsBinaryContentRevision(file, file, versionInfo, settings, myProject);
101 else {
102 return new CvsContentRevision(file, file, versionInfo, settings, myProject);
105 } else {
106 return null;
110 public ItemLatestState getLastRevision(FilePath filePath) {
111 //return getLastRevision(filePath.getIOFile());
112 VirtualFile parent = filePath.getVirtualFileParent();
113 if (parent == null) {
114 parent = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(filePath.getParentPath().getIOFile());
116 if (parent != null) {
117 return getLastState(parent, filePath.getName());
119 return new ItemLatestState(new CvsRevisionNumber("HEAD"), true);
122 public VcsRevisionNumber getLatestCommittedRevision(VirtualFile vcsRoot) {
123 // todo
124 return null;
127 private ItemLatestState getLastRevision(final File file) {
128 // shouldn't use sticky date: we are to get latest revision that exists _in repository_
129 CvsOperationExecutor executor = new CvsOperationExecutor(myProject);
130 final List<File> files = Collections.singletonList(file);
131 final StatusOperation statusOperation = new StatusOperation(files) {
132 @Override
133 protected Command createCommand(CvsRootProvider root, CvsExecutionEnvironment cvsExecutionEnvironment) {
134 final StatusCommand command = (StatusCommand) super.createCommand(root, cvsExecutionEnvironment);
135 command.setIncludeTags(true);
136 return command;
139 final Ref<Boolean> success = new Ref<Boolean>();
140 final CvsOperationExecutorCallback callback = new CvsOperationExecutorCallback() {
141 public void executionFinished(final boolean successfully) {
144 public void executionFinishedSuccessfully() {
145 success.set(Boolean.TRUE);
148 public void executeInProgressAfterAction(final ModalityContext modaityContext) {
151 final CommandCvsHandler cvsHandler = new CommandCvsHandler(CvsBundle.message("operation.name.get.file.status"), statusOperation) {
152 @Override
153 protected boolean runInReadThread() {
154 return false;
157 //executor.performActionSync(cvsHandler, callback);
159 if (Boolean.TRUE.equals(success.get())) {
160 if ((statusOperation.getStickyDate() != null) || (statusOperation.getStickyTag() != null)) {
161 final String headRevision = getHeadRevisionFromLog(statusOperation.getRepositoryRevision(), file);
162 if (headRevision != null) {
163 return new ItemLatestState(new CvsRevisionNumber(headRevision),
164 (statusOperation.getStatus() != null) && (! FileStatus.REMOVED.equals(statusOperation.getStatus())));
166 } else {
167 return new ItemLatestState(new CvsRevisionNumber(statusOperation.getRepositoryRevision()),
168 (statusOperation.getStatus() != null) && (! FileStatus.REMOVED.equals(statusOperation.getStatus())));
172 return new ItemLatestState(new CvsRevisionNumber("HEAD"), true);
175 private ItemLatestState getLastState(final VirtualFile parent, final String name) {
176 final Entry entry = CvsEntriesManager.getInstance().getEntryFor(parent, name);
177 if (entry == null) return new ItemLatestState(new CvsRevisionNumber("HEAD"), true);
178 if (entry.getStickyDate() != null || entry.getStickyTag() != null || entry.getStickyRevision() != null) {
179 final String headRevision = getHeadRevisionFromLog(entry.getRevision(), new File(parent.getPath(), name));
180 if (headRevision != null) {
181 return new ItemLatestState(new CvsRevisionNumber(headRevision), (! entry.isRemoved()));
183 } else {
184 return new ItemLatestState(new CvsRevisionNumber(entry.getRevision()), (! entry.isRemoved()));
186 return new ItemLatestState(new CvsRevisionNumber("HEAD"), true);
189 @Nullable
190 private static String getHeadRevisionFromLog(final String latestKnownRevision, final File file) {
191 final LogOperation operation = new LogOperation(Collections.<FilePath>singletonList(new FilePathImpl(file, false))) {
192 @Override
193 protected Command createCommand(CvsRootProvider root, CvsExecutionEnvironment cvsExecutionEnvironment) {
194 final LogCommand command = (LogCommand) super.createCommand(root, cvsExecutionEnvironment);
195 command.setRevisionFilter(latestKnownRevision + ":");
196 return command;
199 final Ref<Boolean> logSuccess = new Ref<Boolean>(Boolean.TRUE);
200 final ModalityContext context = ModalityContextImpl.NON_MODAL;
201 final CvsExecutionEnvironment cvsExecutionEnvironment = new CvsExecutionEnvironment(new CvsMessagesAdapter(),
202 CvsExecutionEnvironment.DUMMY_STOPPER, new ErrorProcessor() {
203 public void addError(VcsException ex) {
204 logSuccess.set(Boolean.FALSE);
206 public void addWarning(VcsException ex) {
208 public List getErrors() {
209 return null;
211 }, context, PostCvsActivity.DEAF);
212 try {
213 // should already be logged in
214 //operation.login(context);
215 operation.execute(cvsExecutionEnvironment);
217 catch (VcsException e) {
220 catch (CommandAbortedException e) {
223 if (Boolean.TRUE.equals(logSuccess.get())) {
224 final List<LogInformation> informations = operation.getLogInformationList();
225 if (informations != null && (! informations.isEmpty())) {
226 return informations.get(0).getHeadRevision();
229 return null;