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
.openapi
.vcs
.impl
;
18 import com
.intellij
.openapi
.project
.Project
;
19 import com
.intellij
.openapi
.util
.Comparing
;
20 import com
.intellij
.openapi
.vcs
.*;
21 import com
.intellij
.openapi
.vfs
.VirtualFile
;
22 import com
.intellij
.util
.Processor
;
26 public class VcsRootIterator
{
27 // folder path to files to be excluded
28 private final Map
<String
, MyRootFilter
> myOtherVcsFolders
;
29 private ExcludedFileIndex myExcludedFileIndex
;
31 public VcsRootIterator(final Project project
, final AbstractVcs vcs
) {
32 final ProjectLevelVcsManager plVcsManager
= ProjectLevelVcsManager
.getInstance(project
);
33 myOtherVcsFolders
= new HashMap
<String
, MyRootFilter
>();
34 myExcludedFileIndex
= ExcludedFileIndex
.getInstance(project
);
36 final VcsRoot
[] allRoots
= plVcsManager
.getAllVcsRoots();
37 final VirtualFile
[] roots
= plVcsManager
.getRootsUnderVcs(vcs
);
38 for (VirtualFile root
: roots
) {
39 final MyRootFilter rootPresentFilter
= new MyRootFilter(root
, vcs
.getName());
40 rootPresentFilter
.init(allRoots
);
41 myOtherVcsFolders
.put(root
.getUrl(), rootPresentFilter
);
45 public boolean acceptFolderUnderVcs(final VirtualFile vcsRoot
, final VirtualFile file
) {
46 final String vcsUrl
= vcsRoot
.getUrl();
47 final MyRootFilter rootFilter
= myOtherVcsFolders
.get(vcsUrl
);
48 if ((rootFilter
!= null) && (! rootFilter
.accept(file
))) {
51 if (myExcludedFileIndex
.isExcludedFile(file
)) return false;
55 private static class MyRootFilter
{
56 private final VirtualFile myRoot
;
57 private final String myVcsName
;
60 private final List
<String
> myExcludedByOtherVcss
;
62 private MyRootFilter(final VirtualFile root
, final String vcsName
) {
66 myExcludedByOtherVcss
= new LinkedList
<String
>();
69 private void init(final VcsRoot
[] allRoots
) {
70 final String ourPath
= myRoot
.getUrl();
72 for (VcsRoot root
: allRoots
) {
73 if (Comparing
.equal(root
.vcs
.getName(), myVcsName
)) continue;
74 final String url
= root
.path
.getUrl();
75 if (url
.startsWith(ourPath
)) {
76 myExcludedByOtherVcss
.add(url
);
80 Collections
.sort(myExcludedByOtherVcss
, StringLenComparator
.getDescendingInstance());
83 public boolean accept(final VirtualFile vf
) {
84 final String url
= vf
.getUrl();
85 for (String excludedByOtherVcs
: myExcludedByOtherVcss
) {
86 // use the fact that they are sorted
87 if (url
.length() > excludedByOtherVcs
.length()) return true;
88 if (url
.startsWith(excludedByOtherVcs
)) return false;
94 public static boolean iterateVcsRoot(final Project project
, final VirtualFile root
, final Processor
<FilePath
> processor
) {
95 final MyRootIterator rootIterator
= new MyRootIterator(project
, root
, processor
);
96 return rootIterator
.iterate();
99 private static class MyRootIterator
{
100 private final Processor
<FilePath
> myProcessor
;
101 private final LinkedList
<VirtualFile
> myQueue
;
102 private final MyRootFilter myRootPresentFilter
;
103 private final ExcludedFileIndex myExcludedFileIndex
;
105 private MyRootIterator(final Project project
, final VirtualFile root
, final Processor
<FilePath
> processor
) {
106 myProcessor
= processor
;
108 final ProjectLevelVcsManager plVcsManager
= ProjectLevelVcsManager
.getInstance(project
);
109 final AbstractVcs vcs
= plVcsManager
.getVcsFor(root
);
110 myRootPresentFilter
= (vcs
== null) ?
null : new MyRootFilter(root
, vcs
.getName());
111 myExcludedFileIndex
= ExcludedFileIndex
.getInstance(project
);
113 myQueue
= new LinkedList
<VirtualFile
>();
117 public boolean iterate() {
118 while (! myQueue
.isEmpty()) {
119 final VirtualFile current
= myQueue
.removeFirst();
120 if (! myProcessor
.process(new FilePathImpl(current
))) return false;
122 if (current
.isDirectory()) {
123 final VirtualFile
[] files
= current
.getChildren();
125 for (VirtualFile child
: files
) {
126 if (myRootPresentFilter
!= null && (! myRootPresentFilter
.accept(child
))) continue;
127 if (myExcludedFileIndex
.isExcludedFile(child
)) continue;