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
.cvsSupport2
.actions
.merge
.CvsMergeProvider
;
19 import com
.intellij
.cvsSupport2
.actions
.update
.UpdateSettingsOnCvsConfiguration
;
20 import com
.intellij
.cvsSupport2
.config
.CvsConfiguration
;
21 import com
.intellij
.cvsSupport2
.config
.DateOrRevisionSettings
;
22 import com
.intellij
.cvsSupport2
.cvsExecution
.CvsOperationExecutor
;
23 import com
.intellij
.cvsSupport2
.cvsExecution
.CvsOperationExecutorCallback
;
24 import com
.intellij
.cvsSupport2
.cvshandlers
.CommandCvsHandler
;
25 import com
.intellij
.cvsSupport2
.cvshandlers
.CvsHandler
;
26 import com
.intellij
.cvsSupport2
.cvshandlers
.CvsUpdatePolicy
;
27 import com
.intellij
.cvsSupport2
.cvshandlers
.UpdateHandler
;
28 import com
.intellij
.cvsSupport2
.updateinfo
.UpdatedFilesProcessor
;
29 import com
.intellij
.cvsSupport2
.util
.CvsVfsUtil
;
30 import com
.intellij
.openapi
.application
.ApplicationManager
;
31 import com
.intellij
.openapi
.application
.ModalityState
;
32 import com
.intellij
.openapi
.cvsIntegration
.CvsResult
;
33 import com
.intellij
.openapi
.options
.Configurable
;
34 import com
.intellij
.openapi
.progress
.ProgressIndicator
;
35 import com
.intellij
.openapi
.project
.Project
;
36 import com
.intellij
.openapi
.util
.Ref
;
37 import com
.intellij
.openapi
.util
.io
.FileUtil
;
38 import com
.intellij
.openapi
.vcs
.AbstractVcsHelper
;
39 import com
.intellij
.openapi
.vcs
.FilePath
;
40 import com
.intellij
.openapi
.vcs
.VcsKey
;
41 import com
.intellij
.openapi
.vcs
.update
.*;
42 import com
.intellij
.openapi
.vfs
.VfsUtil
;
43 import com
.intellij
.openapi
.vfs
.VirtualFile
;
44 import org
.jetbrains
.annotations
.NotNull
;
47 import java
.util
.ArrayList
;
48 import java
.util
.Collection
;
49 import java
.util
.Collections
;
50 import java
.util
.List
;
52 public class CvsUpdateEnvironment
implements UpdateEnvironment
{
53 private final Project myProject
;
54 private boolean myLastUpdateWasConfigured
= false;
56 public CvsUpdateEnvironment(Project project
) {
61 public void fillGroups(UpdatedFiles updatedFiles
) {
62 CvsUpdatePolicy
.fillGroups(updatedFiles
);
65 private static class CvsSequentialUpdateContext
implements SequentialUpdatesContext
{
66 private final UpdateSettingsOnCvsConfiguration myConfiguration
;
67 private final String myUpdateTagName
;
68 private final static String error
= "merge.wasnt.started.only.update.was.performed";
70 private CvsSequentialUpdateContext(final UpdateSettingsOnCvsConfiguration configuration
, final String tagName
) {
71 myUpdateTagName
= tagName
;
72 myConfiguration
= configuration
;
76 public String
getMessageWhenInterruptedBeforeStart() {
77 String mergeString
= "-j " + myConfiguration
.getBranch1ToMergeWith();
78 if (myConfiguration
.getBranch2ToMergeWith() != null) {
79 mergeString
+= " -j " + myConfiguration
.getBranch2ToMergeWith();
81 return "Merge (" + mergeString
+ ") wasn't started, only update (-r " + myUpdateTagName
+ ") was performed";
84 public boolean shouldFail() {
88 public UpdateSettingsOnCvsConfiguration
getConfiguration() {
89 return myConfiguration
;
93 private UpdateSettingsOnCvsConfiguration
createSettingsAndUpdateContext(final CvsConfiguration cvsConfiguration
,
94 @NotNull final Ref
<SequentialUpdatesContext
> contextRef
) {
95 if (contextRef
.get() != null) {
96 final CvsSequentialUpdateContext cvsContext
= (CvsSequentialUpdateContext
) contextRef
.get();
98 return cvsContext
.getConfiguration();
101 if ((! cvsConfiguration
.CLEAN_COPY
) && cvsConfiguration
.UPDATE_DATE_OR_REVISION_SETTINGS
.overridesDefault() &&
102 (cvsConfiguration
.MERGING_MODE
!= CvsConfiguration
.DO_NOT_MERGE
)) {
103 // split into 2 updates
104 final UpdateSettingsOnCvsConfiguration secondUpdate
= new UpdateSettingsOnCvsConfiguration(
105 cvsConfiguration
.PRUNE_EMPTY_DIRECTORIES
, cvsConfiguration
.MERGING_MODE
, cvsConfiguration
.MERGE_WITH_BRANCH1_NAME
,
106 cvsConfiguration
.MERGE_WITH_BRANCH2_NAME
, cvsConfiguration
.CREATE_NEW_DIRECTORIES
, cvsConfiguration
.UPDATE_KEYWORD_SUBSTITUTION
,
107 new DateOrRevisionSettings(), cvsConfiguration
.MAKE_NEW_FILES_READONLY
, cvsConfiguration
.CLEAN_COPY
, cvsConfiguration
.RESET_STICKY
);
108 contextRef
.set(new CvsSequentialUpdateContext(secondUpdate
, cvsConfiguration
.UPDATE_DATE_OR_REVISION_SETTINGS
.asString()));
110 return new UpdateSettingsOnCvsConfiguration(
111 cvsConfiguration
.PRUNE_EMPTY_DIRECTORIES
, CvsConfiguration
.DO_NOT_MERGE
, null, null, cvsConfiguration
.CREATE_NEW_DIRECTORIES
,
112 cvsConfiguration
.UPDATE_KEYWORD_SUBSTITUTION
, cvsConfiguration
.UPDATE_DATE_OR_REVISION_SETTINGS
,
113 cvsConfiguration
.MAKE_NEW_FILES_READONLY
, cvsConfiguration
.CLEAN_COPY
, cvsConfiguration
.RESET_STICKY
);
116 return new UpdateSettingsOnCvsConfiguration(cvsConfiguration
, cvsConfiguration
.CLEAN_COPY
, cvsConfiguration
.RESET_STICKY
);
121 public UpdateSession
updateDirectories(@NotNull FilePath
[] contentRoots
, final UpdatedFiles updatedFiles
, ProgressIndicator progressIndicator
,
122 @NotNull final Ref
<SequentialUpdatesContext
> contextRef
) {
123 CvsConfiguration cvsConfiguration
= CvsConfiguration
.getInstance(myProject
);
124 if (!myLastUpdateWasConfigured
) {
125 cvsConfiguration
.CLEAN_COPY
= false;
126 cvsConfiguration
.RESET_STICKY
= false;
128 myLastUpdateWasConfigured
= false;
131 final UpdateSettingsOnCvsConfiguration updateSettings
= createSettingsAndUpdateContext(cvsConfiguration
, contextRef
);
132 final UpdateHandler handler
= CommandCvsHandler
.createUpdateHandler(contentRoots
, updateSettings
, myProject
, updatedFiles
);
133 handler
.addCvsListener(new UpdatedFilesProcessor(myProject
, updatedFiles
));
134 CvsOperationExecutor cvsOperationExecutor
= new CvsOperationExecutor(true, myProject
, ModalityState
.defaultModalityState());
135 cvsOperationExecutor
.setShowErrors(false);
136 cvsOperationExecutor
.performActionSync(handler
, CvsOperationExecutorCallback
.EMPTY
);
137 final CvsResult result
= cvsOperationExecutor
.getResult();
138 return createUpdateSessionAdapter(updatedFiles
, result
);
141 cvsConfiguration
.CLEAN_COPY
= false;
142 cvsConfiguration
.RESET_STICKY
= false;
146 private UpdateSessionAdapter
createUpdateSessionAdapter(final UpdatedFiles updatedFiles
, final CvsResult result
) {
147 return new UpdateSessionAdapter(result
.getErrorsAndWarnings(), result
.isCanceled()) {
148 public void onRefreshFilesCompleted() {
149 final FileGroup mergedWithConflictsGroup
= updatedFiles
.getGroupById(FileGroup
.MERGED_WITH_CONFLICT_ID
);
150 final FileGroup binaryMergedGroup
= updatedFiles
.getGroupById(CvsUpdatePolicy
.BINARY_MERGED_ID
);
151 if (!mergedWithConflictsGroup
.isEmpty() || !binaryMergedGroup
.isEmpty()) {
152 Collection
<String
> paths
= new ArrayList
<String
>();
153 paths
.addAll(mergedWithConflictsGroup
.getFiles());
154 paths
.addAll(binaryMergedGroup
.getFiles());
156 final List
<VirtualFile
> list
= invokeManualMerging(paths
, myProject
);
157 FileGroup mergedGroup
= updatedFiles
.getGroupById(FileGroup
.MERGED_ID
);
158 final VcsKey vcsKey
= CvsVcs2
.getKey();
159 for(VirtualFile mergedFile
: list
) {
160 String path
= FileUtil
.toSystemDependentName(mergedFile
.getPresentableUrl());
161 mergedWithConflictsGroup
.remove(path
);
162 binaryMergedGroup
.remove(path
);
163 mergedGroup
.add(path
, vcsKey
, null);
170 private static List
<VirtualFile
> invokeManualMerging(Collection
<String
> paths
, Project project
) {
171 final List
<VirtualFile
> readOnlyFiles
= new ArrayList
<VirtualFile
>();
172 final List
<VirtualFile
> files
= new ArrayList
<VirtualFile
>();
174 for (final String path
: paths
) {
175 final VirtualFile virtualFile
= CvsVfsUtil
.findFileByIoFile(new File(path
));
176 if (virtualFile
!= null) {
177 files
.add(virtualFile
);
178 if (!virtualFile
.isWritable()) {
179 readOnlyFiles
.add(virtualFile
);
184 if (readOnlyFiles
.size() > 0) {
185 final CvsHandler editHandler
= CommandCvsHandler
.createEditHandler(VfsUtil
.toVirtualFileArray(readOnlyFiles
),
186 CvsConfiguration
.getInstance(project
).RESERVED_EDIT
);
187 new CvsOperationExecutor(true, project
, ModalityState
.current()).performActionSync(editHandler
, CvsOperationExecutorCallback
.EMPTY
);
188 ApplicationManager
.getApplication().runWriteAction(new Runnable() {
190 for(VirtualFile file
: readOnlyFiles
) {
191 file
.refresh(false, false);
197 if (! files
.isEmpty()) {
198 return AbstractVcsHelper
.getInstance(project
).showMergeDialog(files
, new CvsMergeProvider());
200 return Collections
.emptyList();
204 public Configurable
createConfigurable(Collection
<FilePath
> files
) {
205 myLastUpdateWasConfigured
= true;
206 CvsConfiguration
.getInstance(myProject
).CLEAN_COPY
= false;
207 CvsConfiguration
.getInstance(myProject
).RESET_STICKY
= false;
208 return new UpdateConfigurable(myProject
, files
);
211 public boolean validateOptions(final Collection
<FilePath
> roots
) {