SVN: do not log process canceled exception
[fedora-idea.git] / plugins / svn4idea / src / org / jetbrains / idea / svn / SvnBranchConfigurationManager.java
blob64853c0c76a4540c81132b4fb7fd1b7339b2cda2
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.
17 package org.jetbrains.idea.svn;
19 import com.intellij.openapi.application.Application;
20 import com.intellij.openapi.application.ApplicationManager;
21 import com.intellij.openapi.components.PersistentStateComponent;
22 import com.intellij.openapi.components.ServiceManager;
23 import com.intellij.openapi.components.State;
24 import com.intellij.openapi.components.Storage;
25 import com.intellij.openapi.diagnostic.Logger;
26 import com.intellij.openapi.progress.ProcessCanceledException;
27 import com.intellij.openapi.project.Project;
28 import com.intellij.openapi.util.Pair;
29 import com.intellij.openapi.util.Ref;
30 import com.intellij.openapi.vcs.ProjectLevelVcsManager;
31 import com.intellij.openapi.vcs.VcsException;
32 import com.intellij.openapi.vcs.changes.committed.VcsConfigurationChangeListener;
33 import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl;
34 import com.intellij.openapi.vcs.impl.VcsInitObject;
35 import com.intellij.openapi.vfs.LocalFileSystem;
36 import com.intellij.openapi.vfs.VirtualFile;
37 import com.intellij.util.PairConsumer;
38 import com.intellij.util.messages.MessageBus;
39 import org.jetbrains.annotations.NotNull;
40 import org.jetbrains.annotations.Nullable;
41 import org.jetbrains.idea.svn.branchConfig.*;
42 import org.jetbrains.idea.svn.integrate.SvnBranchItem;
43 import org.tmatesoft.svn.core.SVNException;
44 import org.tmatesoft.svn.core.SVNURL;
46 import java.io.File;
47 import java.util.*;
49 /**
50 * @author yole
52 @State(
53 name = "SvnBranchConfigurationManager",
54 storages = {
55 @Storage(
56 id ="other",
57 file = "$PROJECT_FILE$"
60 public class SvnBranchConfigurationManager implements PersistentStateComponent<SvnBranchConfigurationManager.ConfigurationBean> {
61 private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.SvnBranchConfigurationManager");
62 private final Project myProject;
63 private final ProjectLevelVcsManager myVcsManager;
65 public SvnBranchConfigurationManager(final Project project, final ProjectLevelVcsManager vcsManager) {
66 myProject = project;
67 myVcsManager = vcsManager;
68 myBunch = new NewRootBunch(project);
71 public static SvnBranchConfigurationManager getInstance(final Project project) {
72 return ServiceManager.getService(project, SvnBranchConfigurationManager.class);
75 public static class ConfigurationBean {
76 public Map<String, SvnBranchConfiguration> myConfigurationMap = new HashMap<String, SvnBranchConfiguration>();
77 /**
78 * version of "support SVN in IDEA". for features tracking. should grow
80 public Long myVersion;
81 public boolean mySupportsUserInfoFilter;
84 public Long getSupportValue() {
85 return myConfigurationBean.myVersion;
88 private ConfigurationBean myConfigurationBean = new ConfigurationBean();
89 private final SvnBranchConfigManager myBunch;
91 public SvnBranchConfigurationNew get(@NotNull final VirtualFile vcsRoot) throws VcsException {
92 return myBunch.getConfig(vcsRoot);
95 public SvnBranchConfigManager getSvnBranchConfigManager() {
96 return myBunch;
99 public void setConfiguration(final VirtualFile vcsRoot, final SvnBranchConfigurationNew configuration) {
100 myBunch.updateForRoot(vcsRoot, new InfoStorage<SvnBranchConfigurationNew>(configuration, InfoReliability.setByUser),
101 new BranchesPreloader(myProject, myBunch, vcsRoot));
103 SvnBranchMapperManager.getInstance().notifyBranchesChanged(myProject, vcsRoot, configuration);
105 final MessageBus messageBus = myProject.getMessageBus();
106 messageBus.syncPublisher(VcsConfigurationChangeListener.BRANCHES_CHANGED).execute(myProject, vcsRoot);
109 public ConfigurationBean getState() {
110 final ConfigurationBean result = new ConfigurationBean();
111 result.myVersion = myConfigurationBean.myVersion;
112 final UrlSerializationHelper helper = new UrlSerializationHelper(SvnVcs.getInstance(myProject));
114 for (VirtualFile root : myBunch.getMapCopy().keySet()) {
115 final String key = root.getPath();
116 final SvnBranchConfigurationNew configOrig = myBunch.getConfig(root);
117 final SvnBranchConfiguration configuration = new SvnBranchConfiguration();
118 configuration.setTrunkUrl(configOrig.getTrunkUrl());
119 configuration.setUserinfoInUrl(configOrig.isUserinfoInUrl());
120 configuration.setBranchUrls(configOrig.getBranchUrls());
121 final HashMap<String, List<SvnBranchItem>> map = new HashMap<String, List<SvnBranchItem>>();
122 final Map<String, InfoStorage<List<SvnBranchItem>>> origMap = configOrig.getBranchMap();
123 for (String origKey : origMap.keySet()) {
124 map.put(origKey, origMap.get(origKey).getValue());
126 configuration.setBranchMap(map);
127 result.myConfigurationMap.put(key, helper.prepareForSerialization(configuration));
129 result.mySupportsUserInfoFilter = true;
130 return result;
133 private static class BranchesPreloader implements PairConsumer<SvnBranchConfigurationNew, SvnBranchConfigurationNew> {
134 private final Project myProject;
135 private final VirtualFile myRoot;
136 private final SvnBranchConfigManager myBunch;
137 private boolean myAll;
139 public BranchesPreloader(Project project, @NotNull final SvnBranchConfigManager bunch, VirtualFile root) {
140 myBunch = bunch;
141 myProject = project;
142 myRoot = root;
145 public void consume(final SvnBranchConfigurationNew prev, final SvnBranchConfigurationNew next) {
146 final Application application = ApplicationManager.getApplication();
147 application.executeOnPooledThread(new Runnable() {
148 public void run() {
149 loadImpl(prev, next);
154 protected void loadImpl(final SvnBranchConfigurationNew prev, final SvnBranchConfigurationNew next) {
155 final Set<String> oldUrls = (prev == null) ? Collections.<String>emptySet() : new HashSet<String>(prev.getBranchUrls());
156 final SvnVcs vcs = SvnVcs.getInstance(myProject);
157 if (! vcs.isVcsBackgroundOperationsAllowed(myRoot)) return;
159 for (String newBranchUrl : next.getBranchUrls()) {
160 if (myAll || (! oldUrls.contains(newBranchUrl))) {
161 new NewRootBunch.BranchesLoadRunnable(myProject, myBunch, newBranchUrl, InfoReliability.defaultValues, myRoot, null).run();
166 public void setAll(boolean all) {
167 myAll = all;
171 public void loadState(final ConfigurationBean object) {
172 final UrlSerializationHelper helper = new UrlSerializationHelper(SvnVcs.getInstance(myProject));
173 final Map<String, SvnBranchConfiguration> map = object.myConfigurationMap;
174 final Map<String, SvnBranchConfiguration> newMap = new HashMap<String, SvnBranchConfiguration>(map.size(), 1);
175 final LocalFileSystem lfs = LocalFileSystem.getInstance();
177 final Set<Pair<VirtualFile, SvnBranchConfigurationNew>> whatToInit = new HashSet<Pair<VirtualFile, SvnBranchConfigurationNew>>();
178 for (Map.Entry<String, SvnBranchConfiguration> entry : map.entrySet()) {
179 final SvnBranchConfiguration configuration = entry.getValue();
180 final VirtualFile root = lfs.refreshAndFindFileByIoFile(new File(entry.getKey()));
181 if (root == null) {
182 LOG.info("root not found: " + entry.getKey());
183 continue;
186 final SvnBranchConfiguration configToConvert;
187 if ((! myConfigurationBean.mySupportsUserInfoFilter) || configuration.isUserinfoInUrl()) {
188 configToConvert = helper.afterDeserialization(entry.getKey(), configuration);
189 } else {
190 configToConvert = configuration;
192 final SvnBranchConfigurationNew newConfig = new SvnBranchConfigurationNew();
193 newConfig.setTrunkUrl(configToConvert.getTrunkUrl());
194 newConfig.setUserinfoInUrl(configToConvert.isUserinfoInUrl());
195 final Map<String, List<SvnBranchItem>> oldMap = configToConvert.getBranchMap();
196 for (String branchUrl : configToConvert.getBranchUrls()) {
197 List<SvnBranchItem> items = oldMap.get(branchUrl);
198 items = ((items == null) || (items.isEmpty())) ? new ArrayList<SvnBranchItem>() : items;
199 whatToInit.add(new Pair<VirtualFile, SvnBranchConfigurationNew>(root, newConfig));
200 newConfig.addBranches(branchUrl, new InfoStorage<List<SvnBranchItem>>(items,
201 (items.isEmpty()) ? InfoReliability.defaultValues : InfoReliability.setByUser));
204 myBunch.updateForRoot(root, new InfoStorage<SvnBranchConfigurationNew>(newConfig, InfoReliability.setByUser), null);
206 ((ProjectLevelVcsManagerImpl) myVcsManager).addInitializationRequest(VcsInitObject.BRANCHES, new Runnable() {
207 public void run() {
208 ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
209 public void run() {
210 try {
211 for (Pair<VirtualFile, SvnBranchConfigurationNew> pair : whatToInit) {
212 final BranchesPreloader branchesPreloader = new BranchesPreloader(myProject, myBunch, pair.getFirst());
213 branchesPreloader.setAll(true);
214 branchesPreloader.loadImpl(null, pair.getSecond());
217 catch (ProcessCanceledException e) {
224 object.myConfigurationMap.clear();
225 object.myConfigurationMap.putAll(newMap);
226 myConfigurationBean = object;
229 private static class UrlSerializationHelper {
230 private final SvnVcs myVcs;
232 private UrlSerializationHelper(final SvnVcs vcs) {
233 myVcs = vcs;
236 public SvnBranchConfiguration prepareForSerialization(final SvnBranchConfiguration configuration) {
237 final Ref<Boolean> withUserInfo = new Ref<Boolean>();
238 final String trunkUrl = serializeUrl(configuration.getTrunkUrl(), withUserInfo);
240 if (Boolean.FALSE.equals(withUserInfo.get())) {
241 return configuration;
244 final List<String> branches = configuration.getBranchUrls();
245 final List<String> newBranchesList = new ArrayList<String>(branches.size());
246 for (String s : branches) {
247 newBranchesList.add(serializeUrl(s, withUserInfo));
250 final Map<String, List<SvnBranchItem>> map = configuration.getBranchMap();
251 final Map<String, List<SvnBranchItem>> newMap = new HashMap<String, List<SvnBranchItem>>(map.size(), 1.0f);
252 for (Map.Entry<String, List<SvnBranchItem>> entry : map.entrySet()) {
253 final List<SvnBranchItem> items = entry.getValue();
254 if (items != null) {
255 final List<SvnBranchItem> newItems = new ArrayList<SvnBranchItem>();
256 for (SvnBranchItem item : items) {
257 newItems.add(new SvnBranchItem(serializeUrl(item.getUrl(), withUserInfo), new java.util.Date(item.getCreationDateMillis()),
258 item.getRevision()));
260 newMap.put(serializeUrl(entry.getKey(), withUserInfo), newItems);
264 final SvnBranchConfiguration result = new SvnBranchConfiguration();
265 result.setTrunkUrl(trunkUrl);
266 result.setBranchUrls(newBranchesList);
267 result.setBranchMap(newMap);
268 result.setUserinfoInUrl(withUserInfo.isNull() ? false : withUserInfo.get());
269 return result;
272 public SvnBranchConfiguration afterDeserialization(final String path, final SvnBranchConfiguration configuration) {
273 if (! configuration.isUserinfoInUrl()) {
274 return configuration;
276 final String userInfo = getUserInfo(path);
277 if (userInfo == null) {
278 return configuration;
281 final String newTrunkUrl = deserializeUrl(configuration.getTrunkUrl(), userInfo);
282 final List<String> branches = configuration.getBranchUrls();
283 final List<String> newBranchesList = new ArrayList<String>(branches.size());
284 for (String s : branches) {
285 newBranchesList.add(deserializeUrl(s, userInfo));
288 final Map<String, List<SvnBranchItem>> map = configuration.getBranchMap();
289 final Map<String, List<SvnBranchItem>> newMap = new HashMap<String, List<SvnBranchItem>>(map.size(), 1.0f);
290 for (Map.Entry<String, List<SvnBranchItem>> entry : map.entrySet()) {
291 final List<SvnBranchItem> items = entry.getValue();
292 if (items != null) {
293 final List<SvnBranchItem> newItems = new ArrayList<SvnBranchItem>();
294 for (SvnBranchItem item : items) {
295 newItems.add(new SvnBranchItem(deserializeUrl(item.getUrl(), userInfo), new java.util.Date(item.getCreationDateMillis()),
296 item.getRevision()));
298 newMap.put(deserializeUrl(entry.getKey(), userInfo), newItems);
302 final SvnBranchConfiguration result = new SvnBranchConfiguration();
303 result.setTrunkUrl(newTrunkUrl);
304 result.setBranchUrls(newBranchesList);
305 result.setBranchMap(newMap);
306 result.setUserinfoInUrl(userInfo != null && userInfo.length() > 0);
307 return result;
310 private String serializeUrl(final String url, final Ref<Boolean> withUserInfo) {
311 if (Boolean.FALSE.equals(withUserInfo.get())) {
312 return url;
314 try {
315 final SVNURL svnurl = SVNURL.parseURIEncoded(url);
316 if (withUserInfo.isNull()) {
317 final String userInfo = svnurl.getUserInfo();
318 withUserInfo.set((userInfo != null) && (userInfo.length() > 0));
320 if (withUserInfo.get()) {
321 return SVNURL.create(svnurl.getProtocol(), null, svnurl.getHost(), svnurl.getPort(), svnurl.getURIEncodedPath(), true).toString();
324 catch (SVNException e) {
327 return url;
330 @Nullable
331 private String getUserInfo(final String path) {
332 final SVNURL svnurl = myVcs.getSvnFileUrlMapping().getUrlForFile(new File(path));
333 return svnurl != null ? svnurl.getUserInfo() : null;
336 private String deserializeUrl(final String url, final String userInfo) {
337 try {
338 final SVNURL svnurl = SVNURL.parseURIEncoded(url);
339 return SVNURL.create(svnurl.getProtocol(), userInfo, svnurl.getHost(), svnurl.getPort(), svnurl.getURIEncodedPath(), true).toString();
340 } catch (SVNException e) {
341 return url;