1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.start;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.nio.file.FileSystem;
24 import java.nio.file.FileSystems;
25 import java.nio.file.Files;
26 import java.nio.file.Path;
27 import java.nio.file.PathMatcher;
28
29
30
31
32 public class PathMatchers
33 {
34 private static class NonHiddenMatcher implements PathMatcher
35 {
36 @Override
37 public boolean matches(Path path)
38 {
39 try
40 {
41 return !Files.isHidden(path);
42 }
43 catch (IOException e)
44 {
45 StartLog.debug(e);
46 return false;
47 }
48 }
49 }
50
51 private static final char GLOB_CHARS[] = "*?".toCharArray();
52 private static final char SYNTAXED_GLOB_CHARS[] = "{}[]|:".toCharArray();
53 private static final Path EMPTY_PATH = new File(".").toPath();
54
55
56
57
58
59
60
61
62 private static Path asPath(final String pattern)
63 {
64 String test = pattern;
65 if (test.startsWith("glob:"))
66 {
67 test = test.substring("glob:".length());
68 }
69 else if (test.startsWith("regex:"))
70 {
71 test = test.substring("regex:".length());
72 }
73 return new File(test).toPath();
74 }
75
76 public static PathMatcher getMatcher(String pattern)
77 {
78 FileSystem fs = FileSystems.getDefault();
79
80
81
82 if (pattern.startsWith("glob:") || pattern.startsWith("regex:"))
83 {
84 StartLog.debug("Using Standard " + fs.getClass().getName() + " pattern: " + pattern);
85 return fs.getPathMatcher(pattern);
86 }
87
88
89
90 for (Path root : fs.getRootDirectories())
91 {
92 StartLog.debug("root: " + root);
93 if (pattern.startsWith(root.toString()))
94 {
95 String pat = "glob:" + pattern;
96 StartLog.debug("Using absolute path pattern: " + pat);
97 return fs.getPathMatcher(pat);
98 }
99 }
100
101
102
103 String pat = "glob:**/" + pattern;
104 StartLog.debug("Using relative path pattern: " + pat);
105 return fs.getPathMatcher(pat);
106 }
107
108 public static PathMatcher getNonHidden()
109 {
110 return new NonHiddenMatcher();
111 }
112
113
114
115
116
117
118
119
120 public static Path getSearchRoot(final String pattern)
121 {
122 StringBuilder root = new StringBuilder();
123
124 int start = 0;
125 boolean syntaxed = false;
126 if (pattern.startsWith("glob:"))
127 {
128 start = "glob:".length();
129 syntaxed = true;
130 }
131 else if (pattern.startsWith("regex:"))
132 {
133 start = "regex:".length();
134 syntaxed = true;
135 }
136 int len = pattern.length();
137 int lastSep = 0;
138 for (int i = start; i < len; i++)
139 {
140 int cp = pattern.codePointAt(i);
141 if (cp < 127)
142 {
143 char c = (char)cp;
144
145
146 if (c == '/')
147 {
148 root.append(c);
149 lastSep = root.length();
150 }
151 else if (c == '\\')
152 {
153 root.append("\\");
154 lastSep = root.length();
155
156
157
158 int count = countChars(pattern,i+1,'\\');
159 if (count > 0)
160 {
161
162 i += count;
163 }
164 }
165 else
166 {
167 if (isGlob(c,syntaxed))
168 {
169 break;
170 }
171 root.append(c);
172 }
173 }
174 else
175 {
176 root.appendCodePoint(cp);
177 }
178 }
179
180 String rootPath = root.substring(0,lastSep);
181 if (rootPath.length() <= 0)
182 {
183 return EMPTY_PATH;
184 }
185
186 return asPath(rootPath);
187 }
188
189 private static int countChars(String pattern, int offset, char c)
190 {
191 int count = 0;
192 int len = pattern.length();
193 for (int i = offset; i < len; i++)
194 {
195 if (pattern.charAt(i) == c)
196 {
197 count++;
198 }
199 else
200 {
201 break;
202 }
203 }
204 return count;
205 }
206
207
208
209
210
211
212
213
214 public static boolean isAbsolute(final String pattern)
215 {
216 Path searchRoot = getSearchRoot(pattern);
217 if (searchRoot == EMPTY_PATH)
218 {
219 return false;
220 }
221 return searchRoot.isAbsolute();
222 }
223
224
225
226
227
228
229
230
231
232
233 private static boolean isGlob(char c, boolean syntaxed)
234 {
235 for (char g : GLOB_CHARS)
236 {
237 if (c == g)
238 {
239 return true;
240 }
241 }
242 if (syntaxed)
243 {
244 for (char g : SYNTAXED_GLOB_CHARS)
245 {
246 if (c == g)
247 {
248 return true;
249 }
250 }
251 }
252 return false;
253 }
254 }