KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > core > io > support > PathMatchingResourcePatternResolver


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */

16
17 package org.springframework.core.io.support;
18
19 import java.io.File JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.net.JarURLConnection JavaDoc;
22 import java.net.URL JavaDoc;
23 import java.net.URLConnection JavaDoc;
24 import java.util.Collections JavaDoc;
25 import java.util.Enumeration JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.Set JavaDoc;
28 import java.util.jar.JarEntry JavaDoc;
29 import java.util.jar.JarFile JavaDoc;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33
34 import org.springframework.core.CollectionFactory;
35 import org.springframework.core.io.DefaultResourceLoader;
36 import org.springframework.core.io.FileSystemResource;
37 import org.springframework.core.io.Resource;
38 import org.springframework.core.io.ResourceLoader;
39 import org.springframework.core.io.UrlResource;
40 import org.springframework.util.AntPathMatcher;
41 import org.springframework.util.Assert;
42 import org.springframework.util.PathMatcher;
43 import org.springframework.util.ResourceUtils;
44 import org.springframework.util.StringUtils;
45
46 /**
47  * A ResourcePatternResolver implementation that is able to resolve a specified
48  * resource location path into one or more matching Resources. The source path
49  * may be a simple path which has a one-to-one mapping to a target Resource,
50  * or alternately may contain the special "<code>classpath*:</code>" prefix
51  * and/or internal Ant-style regular expressions (matched using Spring's
52  * <code>PathMatcher</code> utility).
53  * Both of the latter are effectively wildcards.
54  *
55  * <p><b>No Wildcards:</b>
56  *
57  * <p>In the simple case, if the specified location path does not start with the
58  * <code>"classpath*:</code>" prefix, and does not contain a PathMatcher pattern,
59  * this resolver will simply return a single resource via a
60  * <code>getResource()</code> call on the underlying <code>ResourceLoader</code>.
61  * Examples are real URLs such as "<code>file:C:/context.xml</code>", pseudo-URLs
62  * such as "<code>classpath:/context.xml</code>", and simple unprefixed paths
63  * such as "<code>/WEB-INF/context.xml</code>". The latter will resolve in a
64  * fashion specific to the underlaying <code>ResourceLoader</code> (e.g.
65  * <code>ServletContextResource</code> for a <code>WebApplicationContext</code>).
66  *
67  * <p><b>Ant-style Patterns:</b>
68  *
69  * <p>When the path location contains an Ant-style pattern, e.g.:<pre>
70  * /WEB-INF/*-context.xml
71  * com/mycompany/**&#47;applicationContext.xml
72  * file:C:/some/path/*-context.xml
73  * classpath:com/mycompany/**&#47;applicationContext.xml
74  * </pre>the resolver follows a more complex but defined procedure to try to resolve
75  * the wildcard. It produces a <code>Resource</code> for the path up to the last
76  * non-wildcard segment and obtains a <code>URL</code> from it. If this URL is
77  * not a "<code>jar:</code>" URL or container-specific variant (e.g.
78  * "<code>zip:</code>" in WebLogic, "<code>wsjar</code>" in WebSphere", etc.),
79  * then a <code>java.io.File</code> is obtained from it, and used to resolve the
80  * wildcard by walking the filesystem. In the case of a jar URL, the resolver
81  * either gets a code>java.net.JarURLConnection</code> from it, or manually parse
82  * the jar URL, and then traverse the contents of the jar file, to resolve the
83  * wildcards.
84  *
85  * <p><b>Implications on portability:</b>
86  *
87  * <p>If the specified path is already a file URL (either explicitly, or
88  * implicitly because the base <code>ResourceLoader</code> is a filesystem one,
89  * then wildcarding is guaranteed to work in a completely poratable fashion.
90  *
91  * <p>If the specified path is a classpath location, then the resolver must
92  * obtain the last non-wildcard path segment URL via a
93  * <code>Classloader.getResource()</code> call. Since this is just a
94  * node of the path (not the file at the end) it is actually undefined
95  * (in the ClassLoader Javadocs) exactly what sort of a URL is returned in
96  * this case. In practice, it is usually a <code>java.io.File</code> representing
97  * the directory, where the classpath resource resolves to a filesystem
98  * location, or a jar URL of some sort, where the classpath resource resolves
99  * to a jar location. Still, there is a portability concern on this operation.
100  *
101  * <p>If a jar URL is obtained for the last non-wildcard segment, the resolver
102  * must be able to get a <code>java.net.JarURLConnection</code> from it, or
103  * manually parse the jar URL, to be able to walk the contents of the jar,
104  * and resolve the wildcard. This will work in most environments, but will
105  * fail in others, and it is strongly recommended that the wildcard
106  * resolution of resources coming from jars be thoroughly tested in your
107  * specific environment before you rely on it.
108  *
109  * <p><b><code>classpath*:</code> Prefix:</b>
110  *
111  * <p>There is special support for retrieving multiple class path resources with
112  * the same name, via the "<code>classpath*:</code>" prefix. For example,
113  * "<code>classpath*:META-INF/beans.xml</code>" will find all "beans.xml"
114  * files in the class path, be it in "classes" directories or in JAR files.
115  * This is particularly useful for autodetecting config files of the same name
116  * at the same location within each jar file. Internally, this happens via a
117  * <code>ClassLoader.getResources()</code> call, and is completely portable.
118  *
119  * <p>The "classpath*:" prefix can also be combined with a PathMatcher pattern in
120  * the rest of the location path, for example "classpath*:META-INF/*-beans.xml".
121  * In this case, the resolution strategy is fairly simple: a
122  * <code>ClassLoader.getResources()</code> call is used on the last non-wildcard
123  * path segment to get all the matching resources in the class loader hierarchy,
124  * and then off each resource the same PathMatcher resoltion strategy described
125  * above is used for the wildcard subpath.
126  *
127  * <p><b>Other notes:</b>
128  *
129  * <p><b>WARNING:</b> Note that "<code>classpath*:</code>" when combined with
130  * Ant-style patterns will only work reliably with at least one root directory
131  * before the pattern starts, unless the actual target files reside in the file
132  * system. This means that a pattern like "<code>classpath*:*.xml</code>" will
133  * <i>not</i> retrieve files from the root of jar files but rather only from the
134  * root of expanded directories. This originates from a limitation in the JDK's
135  * <code>ClassLoader.getResources()</code> method which only returns file system
136  * locations for a passed-in empty String (indicating potential roots to search).
137  *
138  * <p><b>WARNING:</b> Ant-style patterns with "classpath:" resources are not
139  * guaranteed to find matching resources if the root package to search is available
140  * in multiple class path locations. This is because a resource such as<pre>
141  * com/mycompany/package1/service-context.xml
142  * </pre>may be in only one location, but when a path such as<pre>
143  * classpath:com/mycompany/**&#47;service-context.xml
144  * </pre>is used to try to resolve it, the resolver will work off the (first) URL
145  * returned by <code>getResource("com/mycompany");</code>. If this base package
146  * node exists in multiple classloader locations, the actual end resource may
147  * not be underneath. Therefore, preferably, use "<code>classpath*:<code>" with the same
148  * Ant-style pattern in such a case, which will search <i>all</i> class path
149  * locations that contain the root package.
150  *
151  * @author Juergen Hoeller
152  * @author Colin Sampaleanu
153  * @since 1.0.2
154  * @see #CLASSPATH_ALL_URL_PREFIX
155  * @see org.springframework.util.AntPathMatcher
156  * @see org.springframework.core.io.ResourceLoader#getResource(String)
157  * @see java.lang.ClassLoader#getResources(String)
158  */

159 public class PathMatchingResourcePatternResolver implements ResourcePatternResolver {
160
161     protected final Log logger = LogFactory.getLog(getClass());
162
163     private final ResourceLoader resourceLoader;
164
165     private PathMatcher pathMatcher = new AntPathMatcher();
166
167
168     /**
169      * Create a new PathMatchingResourcePatternResolver with a DefaultResourceLoader.
170      * <p>ClassLoader access will happen via the thread context class loader.
171      * @see org.springframework.core.io.DefaultResourceLoader
172      */

173     public PathMatchingResourcePatternResolver() {
174         this.resourceLoader = new DefaultResourceLoader();
175     }
176
177     /**
178      * Create a new PathMatchingResourcePatternResolver with a DefaultResourceLoader.
179      * @param classLoader the ClassLoader to load classpath resources with,
180      * or <code>null</code> for using the thread context class loader
181      * @see org.springframework.core.io.DefaultResourceLoader
182      */

183     public PathMatchingResourcePatternResolver(ClassLoader JavaDoc classLoader) {
184         this.resourceLoader = new DefaultResourceLoader(classLoader);
185     }
186
187     /**
188      * Create a new PathMatchingResourcePatternResolver.
189      * <p>ClassLoader access will happen via the thread context class loader.
190      * @param resourceLoader the ResourceLoader to load root directories and
191      * actual resources with
192      */

193     public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {
194         Assert.notNull(resourceLoader, "ResourceLoader must not be null");
195         this.resourceLoader = resourceLoader;
196     }
197
198
199     /**
200      * Return the ResourceLoader that this pattern resolver works with.
201      */

202     public ResourceLoader getResourceLoader() {
203         return this.resourceLoader;
204     }
205
206     /**
207      * Return the ClassLoader that this pattern resolver works with
208      * (never <code>null</code>).
209      */

210     public ClassLoader JavaDoc getClassLoader() {
211         return getResourceLoader().getClassLoader();
212     }
213
214     /**
215      * Set the PathMatcher implementation to use for this
216      * resource pattern resolver. Default is AntPathMatcher.
217      * @see org.springframework.util.AntPathMatcher
218      */

219     public void setPathMatcher(PathMatcher pathMatcher) {
220         Assert.notNull(pathMatcher, "PathMatcher must not be null");
221         this.pathMatcher = pathMatcher;
222     }
223
224     /**
225      * Return the PathMatcher that this resource pattern resolver uses.
226      */

227     public PathMatcher getPathMatcher() {
228         return this.pathMatcher;
229     }
230
231
232     public Resource getResource(String JavaDoc location) {
233         return getResourceLoader().getResource(location);
234     }
235
236     public Resource[] getResources(String JavaDoc locationPattern) throws IOException JavaDoc {
237         Assert.notNull(locationPattern, "Location pattern must not be null");
238         if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
239             // a class path resource (multiple resources for same name possible)
240
if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
241                 // a class path resource pattern
242
return findPathMatchingResources(locationPattern);
243             }
244             else {
245                 // all class path resources with the given name
246
return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
247             }
248         }
249         else {
250             // Only look for a pattern after a prefix here
251
// (to not get fooled by a pattern symbol in a strange prefix).
252
int prefixEnd = locationPattern.indexOf(":") + 1;
253             if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {
254                 // a file pattern
255
return findPathMatchingResources(locationPattern);
256             }
257             else {
258                 // a single resource with the given name
259
return new Resource[] {getResourceLoader().getResource(locationPattern)};
260             }
261         }
262     }
263
264
265     /**
266      * Find all class location resources with the given location via the ClassLoader.
267      * @param location the absolute path within the classpath
268      * @return the result as Resource array
269      * @throws IOException in case of I/O errors
270      * @see java.lang.ClassLoader#getResources
271      * @see #convertClassLoaderURL
272      */

273     protected Resource[] findAllClassPathResources(String JavaDoc location) throws IOException JavaDoc {
274         String JavaDoc path = location;
275         if (path.startsWith("/")) {
276             path = path.substring(1);
277         }
278         Enumeration JavaDoc resourceUrls = getClassLoader().getResources(path);
279         Set JavaDoc result = CollectionFactory.createLinkedSetIfPossible(16);
280         while (resourceUrls.hasMoreElements()) {
281             URL JavaDoc url = (URL JavaDoc) resourceUrls.nextElement();
282             result.add(convertClassLoaderURL(url));
283         }
284         return (Resource[]) result.toArray(new Resource[result.size()]);
285     }
286
287     /**
288      * Convert the given URL as returned from the ClassLoader into a Resource object.
289      * <p>The default implementation simply creates a UrlResource instance.
290      * @param url a URL as returned from the ClassLoader
291      * @return the corresponding Resource object
292      * @see java.lang.ClassLoader#getResources
293      * @see org.springframework.core.io.Resource
294      */

295     protected Resource convertClassLoaderURL(URL JavaDoc url) {
296         return new UrlResource(url);
297     }
298
299     /**
300      * Find all resources that match the given location pattern via the
301      * Ant-style PathMatcher. Supports resources in jar files and zip files
302      * and in the file system.
303      * @param locationPattern the location pattern to match
304      * @return the result as Resource array
305      * @throws IOException in case of I/O errors
306      * @see #doFindPathMatchingJarResources
307      * @see #doFindPathMatchingFileResources
308      * @see org.springframework.util.PathMatcher
309      */

310     protected Resource[] findPathMatchingResources(String JavaDoc locationPattern) throws IOException JavaDoc {
311         String JavaDoc rootDirPath = determineRootDir(locationPattern);
312         String JavaDoc subPattern = locationPattern.substring(rootDirPath.length());
313         Resource[] rootDirResources = getResources(rootDirPath);
314         Set JavaDoc result = CollectionFactory.createLinkedSetIfPossible(16);
315         for (int i = 0; i < rootDirResources.length; i++) {
316             Resource rootDirResource = rootDirResources[i];
317             if (isJarResource(rootDirResource)) {
318                 result.addAll(doFindPathMatchingJarResources(rootDirResource, subPattern));
319             }
320             else {
321                 result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern));
322             }
323         }
324         if (logger.isDebugEnabled()) {
325             logger.debug("Resolved location pattern [" + locationPattern + "] to resources " + result);
326         }
327         return (Resource[]) result.toArray(new Resource[result.size()]);
328     }
329
330     /**
331      * Determine the root directory for the given location.
332      * <p>Used for determining the starting point for file matching,
333      * resolving the root directory location to a <code>java.io.File</code>
334      * and passing it into <code>retrieveMatchingFiles</code>, with the
335      * remainder of the location as pattern.
336      * <p>Will return "/WEB-INF" for the pattern "/WEB-INF/*.xml",
337      * for example.
338      * @param location the location to check
339      * @return the part of the location that denotes the root directory
340      * @see #retrieveMatchingFiles
341      */

342     protected String JavaDoc determineRootDir(String JavaDoc location) {
343         int prefixEnd = location.indexOf(":") + 1;
344         int rootDirEnd = location.length();
345         while (rootDirEnd > prefixEnd && getPathMatcher().isPattern(location.substring(prefixEnd, rootDirEnd))) {
346             rootDirEnd = location.lastIndexOf('/', rootDirEnd - 2) + 1;
347         }
348         if (rootDirEnd == 0) {
349             rootDirEnd = prefixEnd;
350         }
351         return location.substring(0, rootDirEnd);
352     }
353
354     /**
355      * Return whether the given resource handle indicates a jar resource
356      * that the <code>doFindPathMatchingJarResources</code> method can handle.
357      * <p>The default implementation checks against the URL protocols
358      * "jar", "zip" and "wsjar" (the latter are used by BEA WebLogic Server
359      * and IBM WebSphere, respectively, but can be treated like jar files).
360      * @param resource the resource handle to check
361      * (usually the root directory to start path matching from)
362      * @see #doFindPathMatchingJarResources
363      * @see org.springframework.util.ResourceUtils#isJarURL
364      */

365     protected boolean isJarResource(Resource resource) throws IOException JavaDoc {
366         return ResourceUtils.isJarURL(resource.getURL());
367     }
368
369     /**
370      * Find all resources in jar files that match the given location pattern
371      * via the Ant-style PathMatcher.
372      * @param rootDirResource the root directory as Resource
373      * @param subPattern the sub pattern to match (below the root directory)
374      * @return the Set of matching Resource instances
375      * @throws IOException in case of I/O errors
376      * @see java.net.JarURLConnection
377      * @see org.springframework.util.PathMatcher
378      */

379     protected Set JavaDoc doFindPathMatchingJarResources(Resource rootDirResource, String JavaDoc subPattern) throws IOException JavaDoc {
380         URLConnection JavaDoc con = rootDirResource.getURL().openConnection();
381         JarFile JavaDoc jarFile = null;
382         String JavaDoc jarFileUrl = null;
383         String JavaDoc rootEntryPath = null;
384
385         if (con instanceof JarURLConnection JavaDoc) {
386             // Should usually be the case for traditional JAR files.
387
JarURLConnection JavaDoc jarCon = (JarURLConnection JavaDoc) con;
388             jarFile = jarCon.getJarFile();
389             jarFileUrl = jarCon.getJarFileURL().toExternalForm();
390             JarEntry JavaDoc jarEntry = jarCon.getJarEntry();
391             rootEntryPath = (jarEntry != null ? jarEntry.getName() : "");
392         }
393         else {
394             // No JarURLConnection -> need to resort to URL file parsing.
395
// We'll assume URLs of the format "jar:path!/entry", with the protocol
396
// being arbitrary as long as following the entry format.
397
// We'll also handle paths with and without leading "file:" prefix.
398
String JavaDoc urlFile = rootDirResource.getURL().getFile();
399             int separatorIndex = urlFile.indexOf(ResourceUtils.JAR_URL_SEPARATOR);
400             jarFileUrl = urlFile.substring(0, separatorIndex);
401             if (jarFileUrl.startsWith(ResourceUtils.FILE_URL_PREFIX)) {
402                 jarFileUrl = jarFileUrl.substring(ResourceUtils.FILE_URL_PREFIX.length());
403             }
404             jarFile = new JarFile JavaDoc(jarFileUrl);
405             jarFileUrl = ResourceUtils.FILE_URL_PREFIX + jarFileUrl;
406             rootEntryPath = urlFile.substring(separatorIndex + ResourceUtils.JAR_URL_SEPARATOR.length());
407         }
408
409         if (logger.isDebugEnabled()) {
410             logger.debug("Looking for matching resources in jar file [" + jarFileUrl + "]");
411         }
412         if (!"".equals(rootEntryPath) && !rootEntryPath.endsWith("/")) {
413             // Root entry path must end with slash to allow for proper matching.
414
// The Sun JRE does not return a slash here, but BEA JRockit does.
415
rootEntryPath = rootEntryPath + "/";
416         }
417         Set JavaDoc result = CollectionFactory.createLinkedSetIfPossible(8);
418         for (Enumeration JavaDoc entries = jarFile.entries(); entries.hasMoreElements();) {
419             JarEntry JavaDoc entry = (JarEntry JavaDoc) entries.nextElement();
420             String JavaDoc entryPath = entry.getName();
421             if (entryPath.startsWith(rootEntryPath)) {
422                 String JavaDoc relativePath = entryPath.substring(rootEntryPath.length());
423                 if (getPathMatcher().match(subPattern, relativePath)) {
424                     result.add(rootDirResource.createRelative(relativePath));
425                 }
426             }
427         }
428         return result;
429     }
430
431     /**
432      * Find all resources in the file system that match the given location pattern
433      * via the Ant-style PathMatcher.
434      * @param rootDirResource the root directory as Resource
435      * @param subPattern the sub pattern to match (below the root directory)
436      * @return the Set of matching Resource instances
437      * @throws IOException in case of I/O errors
438      * @see #retrieveMatchingFiles
439      * @see org.springframework.util.PathMatcher
440      */

441     protected Set JavaDoc doFindPathMatchingFileResources(Resource rootDirResource, String JavaDoc subPattern) throws IOException JavaDoc {
442         File JavaDoc rootDir = null;
443         try {
444             rootDir = rootDirResource.getFile().getAbsoluteFile();
445         }
446         catch (IOException JavaDoc ex) {
447             if (logger.isDebugEnabled()) {
448                 logger.debug("Cannot search for matching files underneath " + rootDirResource +
449                         " because it does not correspond to a directory in the file system", ex);
450             }
451             return Collections.EMPTY_SET;
452         }
453         return doFindMatchingFileSystemResources(rootDir, subPattern);
454     }
455
456     /**
457      * Find all resources in the file system that match the given location pattern
458      * via the Ant-style PathMatcher.
459      * @param rootDir the root directory in the file system
460      * @param subPattern the sub pattern to match (below the root directory)
461      * @return the Set of matching Resource instances
462      * @throws IOException in case of I/O errors
463      * @see #retrieveMatchingFiles
464      * @see org.springframework.util.PathMatcher
465      */

466     protected Set JavaDoc doFindMatchingFileSystemResources(File JavaDoc rootDir, String JavaDoc subPattern) throws IOException JavaDoc {
467         if (logger.isDebugEnabled()) {
468             logger.debug("Looking for matching resources in directory tree [" + rootDir.getPath() + "]");
469         }
470         Set JavaDoc matchingFiles = retrieveMatchingFiles(rootDir, subPattern);
471         Set JavaDoc result = CollectionFactory.createLinkedSetIfPossible(matchingFiles.size());
472         for (Iterator JavaDoc it = matchingFiles.iterator(); it.hasNext();) {
473             File JavaDoc file = (File JavaDoc) it.next();
474             result.add(new FileSystemResource(file));
475         }
476         return result;
477     }
478
479     /**
480      * Retrieve files that match the given path pattern,
481      * checking the given directory and its subdirectories.
482      * @param rootDir the directory to start from
483      * @param pattern the pattern to match against,
484      * relative to the root directory
485      * @return the Set of matching File instances
486      * @throws IOException if directory contents could not be retrieved
487      */

488     protected Set JavaDoc retrieveMatchingFiles(File JavaDoc rootDir, String JavaDoc pattern) throws IOException JavaDoc {
489         if (!rootDir.isDirectory()) {
490             throw new IllegalArgumentException JavaDoc("Resource path [" + rootDir + "] does not denote a directory");
491         }
492         String JavaDoc fullPattern = StringUtils.replace(rootDir.getAbsolutePath(), File.separator, "/");
493         if (!pattern.startsWith("/")) {
494             fullPattern += "/";
495         }
496         fullPattern = fullPattern + StringUtils.replace(pattern, File.separator, "/");
497         Set JavaDoc result = CollectionFactory.createLinkedSetIfPossible(8);
498         doRetrieveMatchingFiles(fullPattern, rootDir, result);
499         return result;
500     }
501
502     /**
503      * Recursively retrieve files that match the given pattern,
504      * adding them to the given result list.
505      * @param fullPattern the pattern to match against,
506      * with preprended root directory path
507      * @param dir the current directory
508      * @param result the Set of matching File instances to add to
509      * @throws IOException if directory contents could not be retrieved
510      */

511     protected void doRetrieveMatchingFiles(String JavaDoc fullPattern, File JavaDoc dir, Set JavaDoc result) throws IOException JavaDoc {
512         if (logger.isDebugEnabled()) {
513             logger.debug("Searching directory [" + dir.getAbsolutePath() +
514                     "] for files matching pattern [" + fullPattern + "]");
515         }
516         File JavaDoc[] dirContents = dir.listFiles();
517         if (dirContents == null) {
518             throw new IOException JavaDoc("Could not retrieve contents of directory [" + dir.getAbsolutePath() + "]");
519         }
520         boolean dirDepthNotFixed = (fullPattern.indexOf("**") != -1);
521         for (int i = 0; i < dirContents.length; i++) {
522             String JavaDoc currPath = StringUtils.replace(dirContents[i].getAbsolutePath(), File.separator, "/");
523             if (dirContents[i].isDirectory() &&
524                     (dirDepthNotFixed ||
525                     StringUtils.countOccurrencesOf(currPath, "/") < StringUtils.countOccurrencesOf(fullPattern, "/"))) {
526                 doRetrieveMatchingFiles(fullPattern, dirContents[i], result);
527             }
528             if (getPathMatcher().match(fullPattern, currPath)) {
529                 result.add(dirContents[i]);
530             }
531         }
532     }
533
534 }
535
Popular Tags