polish code
[teamcity/dotNetPackagesSupport.git] / nuget-agent / src / jetbrains / buildServer / nuget / agent / runner / publish / fsScanner / DirectoryScanner.java
1 /*\r
2  * Copyright 2000-2011 JetBrains s.r.o.\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  * http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 package jetbrains.buildServer.nuget.agent.runner.publish.fsScanner;\r
17 \r
18 import com.intellij.openapi.diagnostic.Logger;\r
19 import org.jetbrains.annotations.NotNull;\r
20 \r
21 import java.io.File;\r
22 import java.util.ArrayList;\r
23 import java.util.Collection;\r
24 import java.util.Collections;\r
25 import java.util.List;\r
26 \r
27 /// <summary>\r
28 /// Nant-syntax wildcard matcher on file system trees\r
29 /// </summary>\r
30 public class DirectoryScanner {\r
31   private static final Logger LOG = Logger.getInstance(DirectoryScanner.class.getName());\r
32 \r
33   public static Collection<File> FindFiles(@NotNull File root, Collection<String> includes, Collection<String> excludes) {\r
34     return FindFiles(new RealFileSystem(), new RealDirectoryEntry(new FileSystemPath(root)), includes, excludes);\r
35   }\r
36 \r
37   private static Collection<File> FindFiles(IFileSystem fs, IDirectoryEntry root, Collection<String> includes, Collection<String> excludes) {\r
38     List<Wildcard> basePath = BuildSearchPrefix(root, fs.CaseSensitive());\r
39 \r
40     List<FileSystemPath> result = new ArrayList<FileSystemPath>();\r
41     FindFilesRec(\r
42             fs.Root(),\r
43             result,\r
44             ToAntPatternState(fs, basePath, fs.CaseSensitive(), includes),\r
45             ToAntPatternState(fs, basePath, fs.CaseSensitive(), excludes)\r
46     );\r
47 \r
48     List<File> foundFiles = new ArrayList<File>();\r
49     for (FileSystemPath path : result) {\r
50       foundFiles.add(path.FilePath());\r
51     }\r
52     return foundFiles;\r
53   }\r
54 \r
55   private static List<Wildcard> BuildSearchPrefix(@NotNull IDirectoryEntry root, boolean caseSensitive) {\r
56     List<Wildcard> wildcardPrefix = new ArrayList<Wildcard>();\r
57     while (root.Parent() != null) {\r
58       wildcardPrefix.add(new Wildcard(root.Name(), caseSensitive));\r
59       root = root.Parent();\r
60     }\r
61     Collections.reverse(wildcardPrefix);\r
62 \r
63     return wildcardPrefix;\r
64   }\r
65 \r
66   private static List<AntPatternState> ToAntPatternState(IFileSystem fs, List<Wildcard> wildcardPrefix, boolean caseSensitive, Collection<String> patterns) {\r
67     List<AntPatternState> result = new ArrayList<AntPatternState>();\r
68     for (String x : patterns) {\r
69       result.add(new AntPatternState(ParsePattern(fs, wildcardPrefix, caseSensitive, x)));\r
70     }\r
71     return result;\r
72   }\r
73 \r
74   private static List<Wildcard> ParsePattern(IFileSystem fs, List<Wildcard> rootPrefix, boolean caseSensitive, String pattern) {\r
75     List<Wildcard> wildcards = AntPatternUtil.ParsePattern(pattern, caseSensitive);\r
76 \r
77     if (fs.IsPathAbsolute(pattern))\r
78       return wildcards;\r
79 \r
80     List<Wildcard> result = new ArrayList<Wildcard>();\r
81     result.addAll(rootPrefix);\r
82     result.addAll(wildcards);\r
83 \r
84     return result;\r
85   }\r
86 \r
87   private interface AnyPredicate {\r
88     boolean matches(AntPatternState.MatchResult r);\r
89   }\r
90 \r
91   private static boolean Any(List<AntPatternState> state, String component, AnyPredicate predicate, List<AntPatternState> newState) {\r
92     boolean any = false;\r
93     newState.clear();\r
94 \r
95     for (AntPatternState aState : state) {\r
96       final AntPatternState.AntPatternStateMatch enter = aState.Enter(component);\r
97       AntPatternState.MatchResult match = enter.getResult();\r
98       newState.add(enter.getState());\r
99 \r
100       if (predicate.matches(match))\r
101         any = true;\r
102     }\r
103 \r
104     return any;\r
105   }\r
106 \r
107   private static void FindFilesRec(IDirectoryEntry directory, List<FileSystemPath> result, List<AntPatternState> includeState, List<AntPatternState> excludeState) {\r
108     LOG.debug("Scanning directory: " + directory.Name());\r
109     for (IFileEntry file : directory.Files()) {\r
110       List<AntPatternState> newState = new ArrayList<AntPatternState>();\r
111 \r
112       if (!Any(includeState, file.Name(), Predicate(false, AntPatternState.MatchResult.YES), newState))\r
113         continue;\r
114 \r
115       newState.clear();\r
116       if (Any(excludeState, file.Name(), Predicate(false, AntPatternState.MatchResult.YES), newState))\r
117         continue;\r
118 \r
119       result.add(file.Path());\r
120     }\r
121 \r
122     for (IDirectoryEntry subEntry : directory.Subdirectories()) {\r
123       String name = subEntry.Name();\r
124 \r
125       List<AntPatternState> newIncludeState = new ArrayList<AntPatternState>();\r
126       if (!Any(includeState, name, Predicate(true, AntPatternState.MatchResult.NO), newIncludeState))\r
127         continue;\r
128 \r
129       List<AntPatternState> newExcludeState = new ArrayList<AntPatternState>();\r
130       if (Any(excludeState, name, Predicate(false, AntPatternState.MatchResult.YES), newExcludeState))\r
131         continue;\r
132 \r
133       FindFilesRec(subEntry, result, newIncludeState, newExcludeState);\r
134     }\r
135   }\r
136 \r
137   public static AnyPredicate Predicate(final boolean not, final AntPatternState.MatchResult state) {\r
138     return new AnyPredicate() {\r
139       public boolean matches(AntPatternState.MatchResult r) {\r
140         return not ? state != r : state == r;\r
141       }\r
142     };\r
143   }\r
144 \r
145 }\r