IDEADEV-41062 (Map help button of "Import into Subversion" dialog box)
[fedora-idea.git] / plugins / svn4idea / src / org / jetbrains / idea / svn / ForNestedRootChecker.java
blob8c9e4aea84ff4ecce9b282494157dddb3f772fac
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 org.jetbrains.idea.svn;
18 import com.intellij.openapi.util.Getter;
19 import com.intellij.openapi.vcs.impl.VcsRootIterator;
20 import com.intellij.openapi.vfs.VfsUtil;
21 import com.intellij.openapi.vfs.VirtualFile;
22 import com.intellij.openapi.progress.ProcessCanceledException;
23 import org.jetbrains.annotations.Nullable;
24 import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;
25 import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
26 import org.tmatesoft.svn.core.wc.SVNInfo;
27 import org.tmatesoft.svn.core.wc.SVNWCClient;
29 import java.util.*;
31 public class ForNestedRootChecker {
32 static class DirInfo {
33 private final VirtualFile myFile;
34 private final String myUrl;
36 DirInfo(final VirtualFile file, final String url) {
37 myFile = file;
38 myUrl = url;
41 public VirtualFile getFile() {
42 return myFile;
45 public String getUrl() {
46 return myUrl;
50 private static class UrlConstructor {
51 final SvnVcs myVcs;
52 final SVNWCClient myClient;
54 private UrlConstructor(final SvnVcs vcs) {
55 myVcs = vcs;
56 myClient = myVcs.createWCClient();
59 @Nullable
60 public Real createReal(final VirtualFile file, final VirtualFile vcsRoot) {
61 final SVNInfo info = myVcs.getInfo(file);
62 if (info == null || info.getRepositoryRootURL() == null || info.getURL() == null) {
63 return null;
65 return new Real(file, info, vcsRoot);
68 public Node createReplaceable(final VirtualFile file) {
69 return new Node(file, null);
72 public Node createSupposed(final Real parent, final VirtualFile child) {
73 return new Node(child, getForChild(parent.getUrl(), child.getName()));
76 public boolean replaceWithReal(final Real real, final Node supposed) {
77 return supposed.getUrl() == null || ((supposed.getUrl() != null) && (! supposed.getUrl().equals(real.getUrl())));
80 @Nullable
81 private String getSupposedUrl(final String parentUrl, final List<String> subpath) {
82 if (parentUrl == null) return null;
83 final StringBuilder sb = new StringBuilder();
84 for (String s : subpath) {
85 sb.append(s).append('/');
87 if (sb.length() > 0) {
88 sb.deleteCharAt(sb.length() - 1);
90 return SVNPathUtil.append(parentUrl, sb.toString());
93 public String getForChild(final String parentUrl, final String childName) {
94 return parentUrl == null ? null : SVNPathUtil.append(parentUrl, SVNEncodingUtil.uriEncode(childName));
98 public static<T extends RootUrlPair> void filterOutSuperfluousChildren(final SvnVcs vcs, final List<T> list,
99 final List<T> result) {
100 final UrlConstructor constructor = new UrlConstructor(vcs);
102 Collections.sort(list, new Comparator<RootUrlPair>() {
103 public int compare(final RootUrlPair o1, final RootUrlPair o2) {
104 return o1.getVirtualFile().getPath().compareTo(o2.getVirtualFile().getPath());
108 for (int i = 0; i < list.size(); i++) {
109 final T child = list.get(i);
110 boolean add = true;
111 for (T parent : result) {
112 if (parent.getVirtualFile().getPath().equals(child.getVirtualFile().getPath())) {
113 add = false;
114 break;
116 final List<String> subpath = subpathIfAncestor(parent.getVirtualFile(), child.getVirtualFile());
117 if (subpath != null) {
118 // get child's supposed and real urls
119 final String supposed = constructor.getSupposedUrl(parent.getUrl(), subpath);
120 if (supposed.equals(child.getUrl())) {
121 add = false;
122 break;
126 if (add) {
127 result.add(child);
132 @Nullable
133 private static List<String> subpathIfAncestor(final VirtualFile parent, final VirtualFile child) {
134 if (! VfsUtil.isAncestor(parent, child, true)) return null;
136 final List<String> result = new ArrayList<String>();
137 VirtualFile tmp = child;
138 final String parentPath = parent.getPath();
139 while ((tmp != null) && (! tmp.getPath().equals(parentPath))) {
140 result.add(tmp.getName());
141 tmp = tmp.getParent();
143 Collections.reverse(result);
144 return result;
147 /*public static List<Real> getAllNestedWorkingCopies(final VirtualFile[] roots, final SvnVcs vcs, final boolean goIntoNested) {
148 if (goIntoNested) {
149 FilterDescendantVirtualFiles.filter(Arrays.asList(roots));
152 final VcsRootIterator rootIterator = new VcsRootIterator(vcs.getProject(), vcs);
153 final List<Real> result = new ArrayList<Real>();
154 for (VirtualFile root : roots) {
155 result.addAll(getForOne(root, vcs, goIntoNested, rootIterator));
158 if (! goIntoNested) {
159 final List<Real> filtered = new ArrayList<Real>(result.size());
160 filterOutSuperfluousChildren(vcs, result, filtered);
161 return filtered;
164 return result;
167 public static List<Real> getAllNestedWorkingCopies(final VirtualFile root, final SvnVcs vcs, final boolean goIntoNested, final Getter<Boolean> cancelledGetter) {
168 final VcsRootIterator rootIterator = new VcsRootIterator(vcs.getProject(), vcs);
169 return getForOne(root, vcs, goIntoNested, rootIterator, cancelledGetter);
172 private static List<Real> getForOne(final VirtualFile root, final SvnVcs vcs, final boolean goIntoNested,
173 final VcsRootIterator rootIterator, final Getter<Boolean> cancelledGetter) {
174 final UrlConstructor constructor = new UrlConstructor(vcs);
175 final LinkedList<Node> queue = new LinkedList<Node>();
176 final LinkedList<Real> result = new LinkedList<Real>();
178 queue.add(constructor.createReplaceable(root));
179 while (! queue.isEmpty()) {
180 final Node node = queue.removeFirst();
182 // check self
183 final Real real = constructor.createReal(node.getFile(), root);
184 if (real != null) {
185 if (constructor.replaceWithReal(real, node)) {
186 result.add(real);
187 if (! goIntoNested) continue;
191 // for next step
192 final VirtualFile file = node.getFile();
193 if (file.isDirectory() && (! SvnUtil.isAdminDirectory(file))) {
194 for (VirtualFile child : file.getChildren()) {
195 if (Boolean.TRUE.equals(cancelledGetter.get())) throw new ProcessCanceledException();
196 if (rootIterator.acceptFolderUnderVcs(root, child)) {
197 if (real == null) {
198 queue.add(constructor.createReplaceable(child));
199 } else {
200 queue.add(constructor.createSupposed(real, child));
206 return result;