blob: 509c400f92b172b9d45cf6d5a0c998a02de0604c [file] [log] [blame]
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.cvsSupport2;
import com.intellij.cvsSupport2.actions.merge.CvsMergeProvider;
import com.intellij.cvsSupport2.actions.update.UpdateSettingsOnCvsConfiguration;
import com.intellij.cvsSupport2.config.CvsConfiguration;
import com.intellij.cvsSupport2.config.DateOrRevisionSettings;
import com.intellij.cvsSupport2.cvsExecution.CvsOperationExecutor;
import com.intellij.cvsSupport2.cvsExecution.CvsOperationExecutorCallback;
import com.intellij.cvsSupport2.cvshandlers.CommandCvsHandler;
import com.intellij.cvsSupport2.cvshandlers.CvsHandler;
import com.intellij.cvsSupport2.cvshandlers.CvsUpdatePolicy;
import com.intellij.cvsSupport2.cvshandlers.UpdateHandler;
import com.intellij.cvsSupport2.updateinfo.UpdatedFilesProcessor;
import com.intellij.cvsSupport2.util.CvsVfsUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.cvsIntegration.CvsResult;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.AbstractVcsHelper;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vcs.update.*;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class CvsUpdateEnvironment implements UpdateEnvironment {
private final Project myProject;
private boolean myLastUpdateWasConfigured = false;
public CvsUpdateEnvironment(Project project) {
myProject = project;
}
public void fillGroups(UpdatedFiles updatedFiles) {
CvsUpdatePolicy.fillGroups(updatedFiles);
}
private static class CvsSequentialUpdateContext implements SequentialUpdatesContext {
private final UpdateSettingsOnCvsConfiguration myConfiguration;
private final String myUpdateTagName;
private CvsSequentialUpdateContext(final UpdateSettingsOnCvsConfiguration configuration, final String tagName) {
myUpdateTagName = tagName;
myConfiguration = configuration;
}
@NotNull
public String getMessageWhenInterruptedBeforeStart() {
String mergeString = "-j " + myConfiguration.getBranch1ToMergeWith();
if (myConfiguration.getBranch2ToMergeWith() != null) {
mergeString += " -j " + myConfiguration.getBranch2ToMergeWith();
}
return "Merge (" + mergeString + ") wasn't started, only update (-r " + myUpdateTagName + ") was performed";
}
public boolean shouldFail() {
return true;
}
public UpdateSettingsOnCvsConfiguration getConfiguration() {
return myConfiguration;
}
}
private static UpdateSettingsOnCvsConfiguration createSettingsAndUpdateContext(final CvsConfiguration cvsConfiguration,
@NotNull final Ref<SequentialUpdatesContext> contextRef) {
if (contextRef.get() != null) {
final CvsSequentialUpdateContext cvsContext = (CvsSequentialUpdateContext) contextRef.get();
contextRef.set(null);
return cvsContext.getConfiguration();
}
if ((! cvsConfiguration.CLEAN_COPY) && cvsConfiguration.UPDATE_DATE_OR_REVISION_SETTINGS.overridesDefault() &&
(cvsConfiguration.MERGING_MODE != CvsConfiguration.DO_NOT_MERGE)) {
// split into 2 updates
final UpdateSettingsOnCvsConfiguration secondUpdate = new UpdateSettingsOnCvsConfiguration(
cvsConfiguration.PRUNE_EMPTY_DIRECTORIES, cvsConfiguration.MERGING_MODE, cvsConfiguration.MERGE_WITH_BRANCH1_NAME,
cvsConfiguration.MERGE_WITH_BRANCH2_NAME, cvsConfiguration.CREATE_NEW_DIRECTORIES, cvsConfiguration.UPDATE_KEYWORD_SUBSTITUTION,
new DateOrRevisionSettings(), cvsConfiguration.MAKE_NEW_FILES_READONLY, cvsConfiguration.CLEAN_COPY, cvsConfiguration.RESET_STICKY);
contextRef.set(new CvsSequentialUpdateContext(secondUpdate, cvsConfiguration.UPDATE_DATE_OR_REVISION_SETTINGS.asString()));
return new UpdateSettingsOnCvsConfiguration(
cvsConfiguration.PRUNE_EMPTY_DIRECTORIES, CvsConfiguration.DO_NOT_MERGE, null, null, cvsConfiguration.CREATE_NEW_DIRECTORIES,
cvsConfiguration.UPDATE_KEYWORD_SUBSTITUTION, cvsConfiguration.UPDATE_DATE_OR_REVISION_SETTINGS,
cvsConfiguration.MAKE_NEW_FILES_READONLY, cvsConfiguration.CLEAN_COPY, cvsConfiguration.RESET_STICKY);
} else {
// usual way
return new UpdateSettingsOnCvsConfiguration(cvsConfiguration, cvsConfiguration.CLEAN_COPY, cvsConfiguration.RESET_STICKY);
}
}
@NotNull
public UpdateSession updateDirectories(@NotNull FilePath[] contentRoots, final UpdatedFiles updatedFiles, ProgressIndicator progressIndicator,
@NotNull final Ref<SequentialUpdatesContext> contextRef) {
CvsConfiguration cvsConfiguration = CvsConfiguration.getInstance(myProject);
if (!myLastUpdateWasConfigured) {
cvsConfiguration.CLEAN_COPY = false;
cvsConfiguration.RESET_STICKY = false;
}
myLastUpdateWasConfigured = false;
try {
final UpdateSettingsOnCvsConfiguration updateSettings = createSettingsAndUpdateContext(cvsConfiguration, contextRef);
final UpdateHandler handler = CommandCvsHandler.createUpdateHandler(contentRoots, updateSettings, myProject, updatedFiles);
handler.addCvsListener(new UpdatedFilesProcessor(updatedFiles));
CvsOperationExecutor cvsOperationExecutor = new CvsOperationExecutor(true, myProject, ModalityState.defaultModalityState());
cvsOperationExecutor.setShowErrors(false);
cvsOperationExecutor.performActionSync(handler, CvsOperationExecutorCallback.EMPTY);
final CvsResult result = cvsOperationExecutor.getResult();
return createUpdateSessionAdapter(updatedFiles, result);
}
finally {
cvsConfiguration.CLEAN_COPY = false;
cvsConfiguration.RESET_STICKY = false;
}
}
private UpdateSessionAdapter createUpdateSessionAdapter(final UpdatedFiles updatedFiles, final CvsResult result) {
return new UpdateSessionAdapter(result.getErrorsAndWarnings(), result.isCanceled()) {
public void onRefreshFilesCompleted() {
final FileGroup mergedWithConflictsGroup = updatedFiles.getGroupById(FileGroup.MERGED_WITH_CONFLICT_ID);
final FileGroup binaryMergedGroup = updatedFiles.getGroupById(CvsUpdatePolicy.BINARY_MERGED_ID);
if (!mergedWithConflictsGroup.isEmpty() || !binaryMergedGroup.isEmpty()) {
Collection<String> paths = new ArrayList<String>();
paths.addAll(mergedWithConflictsGroup.getFiles());
paths.addAll(binaryMergedGroup.getFiles());
final List<VirtualFile> list = invokeManualMerging(paths, myProject);
FileGroup mergedGroup = updatedFiles.getGroupById(FileGroup.MERGED_ID);
final VcsKey vcsKey = CvsVcs2.getKey();
for(VirtualFile mergedFile: list) {
String path = FileUtil.toSystemDependentName(mergedFile.getPresentableUrl());
mergedWithConflictsGroup.remove(path);
binaryMergedGroup.remove(path);
mergedGroup.add(path, vcsKey, null);
}
}
}
};
}
private static List<VirtualFile> invokeManualMerging(Collection<String> paths, Project project) {
final List<VirtualFile> readOnlyFiles = new ArrayList<VirtualFile>();
final List<VirtualFile> files = new ArrayList<VirtualFile>();
for (final String path : paths) {
final VirtualFile virtualFile = CvsVfsUtil.findFileByIoFile(new File(path));
if (virtualFile != null) {
files.add(virtualFile);
if (!virtualFile.isWritable()) {
readOnlyFiles.add(virtualFile);
}
}
}
if (readOnlyFiles.size() > 0) {
final CvsHandler editHandler = CommandCvsHandler.createEditHandler(VfsUtil.toVirtualFileArray(readOnlyFiles),
CvsConfiguration.getInstance(project).RESERVED_EDIT);
new CvsOperationExecutor(true, project, ModalityState.current()).performActionSync(editHandler, CvsOperationExecutorCallback.EMPTY);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
for(VirtualFile file: readOnlyFiles) {
file.refresh(false, false);
}
}
});
}
if (! files.isEmpty()) {
return AbstractVcsHelper.getInstance(project).showMergeDialog(files, new CvsMergeProvider());
}
return Collections.emptyList();
}
public Configurable createConfigurable(Collection<FilePath> files) {
myLastUpdateWasConfigured = true;
CvsConfiguration.getInstance(myProject).CLEAN_COPY = false;
CvsConfiguration.getInstance(myProject).RESET_STICKY = false;
return new UpdateConfigurable(myProject, files);
}
public boolean validateOptions(final Collection<FilePath> roots) {
return true;
}
}