Source Code Cross Referenced for PathMatchingResourcePatternResolver.java in  » J2EE » spring-framework-2.5 » org » springframework » core » io » support » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » spring framework 2.5 » org.springframework.core.io.support 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2002-2007 the original author or authors.
003:         *
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         *
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:
017:        package org.springframework.core.io.support;
018:
019:        import java.io.File;
020:        import java.io.IOException;
021:        import java.net.JarURLConnection;
022:        import java.net.URL;
023:        import java.net.URLConnection;
024:        import java.util.Collections;
025:        import java.util.Enumeration;
026:        import java.util.Iterator;
027:        import java.util.LinkedHashSet;
028:        import java.util.Set;
029:        import java.util.jar.JarEntry;
030:        import java.util.jar.JarFile;
031:
032:        import org.apache.commons.logging.Log;
033:        import org.apache.commons.logging.LogFactory;
034:
035:        import org.springframework.core.io.DefaultResourceLoader;
036:        import org.springframework.core.io.FileSystemResource;
037:        import org.springframework.core.io.Resource;
038:        import org.springframework.core.io.ResourceLoader;
039:        import org.springframework.core.io.UrlResource;
040:        import org.springframework.util.AntPathMatcher;
041:        import org.springframework.util.Assert;
042:        import org.springframework.util.PathMatcher;
043:        import org.springframework.util.ResourceUtils;
044:        import org.springframework.util.StringUtils;
045:
046:        /**
047:         * A {@link ResourcePatternResolver} implementation that is able to resolve a
048:         * specified resource location path into one or more matching Resources.
049:         * The source path may be a simple path which has a one-to-one mapping to a
050:         * target {@link org.springframework.core.io.Resource}, or alternatively
051:         * may contain the special "<code>classpath*:</code>" prefix and/or
052:         * internal Ant-style regular expressions (matched using Spring's
053:         * {@link org.springframework.util.AntPathMatcher} utility).
054:         * Both of the latter are effectively wildcards.
055:         *
056:         * <p><b>No Wildcards:</b>
057:         *
058:         * <p>In the simple case, if the specified location path does not start with the
059:         * <code>"classpath*:</code>" prefix, and does not contain a PathMatcher pattern,
060:         * this resolver will simply return a single resource via a
061:         * <code>getResource()</code> call on the underlying <code>ResourceLoader</code>.
062:         * Examples are real URLs such as "<code>file:C:/context.xml</code>", pseudo-URLs
063:         * such as "<code>classpath:/context.xml</code>", and simple unprefixed paths
064:         * such as "<code>/WEB-INF/context.xml</code>". The latter will resolve in a
065:         * fashion specific to the underlying <code>ResourceLoader</code> (e.g. 
066:         * <code>ServletContextResource</code> for a <code>WebApplicationContext</code>).
067:         *
068:         * <p><b>Ant-style Patterns:</b>
069:         *
070:         * <p>When the path location contains an Ant-style pattern, e.g.:
071:         * <pre>
072:         * /WEB-INF/*-context.xml
073:         * com/mycompany/**&#47;applicationContext.xml
074:         * file:C:/some/path/*-context.xml
075:         * classpath:com/mycompany/**&#47;applicationContext.xml</pre>
076:         * the resolver follows a more complex but defined procedure to try to resolve
077:         * the wildcard. It produces a <code>Resource</code> for the path up to the last
078:         * non-wildcard segment and obtains a <code>URL</code> from it. If this URL is
079:         * not a "<code>jar:</code>" URL or container-specific variant (e.g.
080:         * "<code>zip:</code>" in WebLogic, "<code>wsjar</code>" in WebSphere", etc.),
081:         * then a <code>java.io.File</code> is obtained from it, and used to resolve the
082:         * wildcard by walking the filesystem. In the case of a jar URL, the resolver
083:         * either gets a <code>java.net.JarURLConnection</code> from it, or manually parse
084:         * the jar URL, and then traverse the contents of the jar file, to resolve the
085:         * wildcards.
086:         *
087:         * <p><b>Implications on portability:</b>
088:         *
089:         * <p>If the specified path is already a file URL (either explicitly, or
090:         * implicitly because the base <code>ResourceLoader</code> is a filesystem one,
091:         * then wildcarding is guaranteed to work in a completely portable fashion.
092:         *
093:         * <p>If the specified path is a classpath location, then the resolver must
094:         * obtain the last non-wildcard path segment URL via a
095:         * <code>Classloader.getResource()</code> call. Since this is just a
096:         * node of the path (not the file at the end) it is actually undefined
097:         * (in the ClassLoader Javadocs) exactly what sort of a URL is returned in
098:         * this case. In practice, it is usually a <code>java.io.File</code> representing
099:         * the directory, where the classpath resource resolves to a filesystem
100:         * location, or a jar URL of some sort, where the classpath resource resolves
101:         * to a jar location. Still, there is a portability concern on this operation.
102:         *
103:         * <p>If a jar URL is obtained for the last non-wildcard segment, the resolver
104:         * must be able to get a <code>java.net.JarURLConnection</code> from it, or
105:         * manually parse the jar URL, to be able to walk the contents of the jar,
106:         * and resolve the wildcard. This will work in most environments, but will
107:         * fail in others, and it is strongly recommended that the wildcard
108:         * resolution of resources coming from jars be thoroughly tested in your
109:         * specific environment before you rely on it.
110:         *
111:         * <p><b><code>classpath*:</code> Prefix:</b>
112:         *
113:         * <p>There is special support for retrieving multiple class path resources with
114:         * the same name, via the "<code>classpath*:</code>" prefix. For example,
115:         * "<code>classpath*:META-INF/beans.xml</code>" will find all "beans.xml"
116:         * files in the class path, be it in "classes" directories or in JAR files.
117:         * This is particularly useful for autodetecting config files of the same name
118:         * at the same location within each jar file. Internally, this happens via a
119:         * <code>ClassLoader.getResources()</code> call, and is completely portable.
120:         *
121:         * <p>The "classpath*:" prefix can also be combined with a PathMatcher pattern in
122:         * the rest of the location path, for example "classpath*:META-INF/*-beans.xml".
123:         * In this case, the resolution strategy is fairly simple: a
124:         * <code>ClassLoader.getResources()</code> call is used on the last non-wildcard
125:         * path segment to get all the matching resources in the class loader hierarchy,
126:         * and then off each resource the same PathMatcher resolution strategy described
127:         * above is used for the wildcard subpath.
128:         *
129:         * <p><b>Other notes:</b>
130:         *
131:         * <p><b>WARNING:</b> Note that "<code>classpath*:</code>" when combined with
132:         * Ant-style patterns will only work reliably with at least one root directory
133:         * before the pattern starts, unless the actual target files reside in the file
134:         * system. This means that a pattern like "<code>classpath*:*.xml</code>" will
135:         * <i>not</i> retrieve files from the root of jar files but rather only from the
136:         * root of expanded directories. This originates from a limitation in the JDK's
137:         * <code>ClassLoader.getResources()</code> method which only returns file system
138:         * locations for a passed-in empty String (indicating potential roots to search).
139:         *
140:         * <p><b>WARNING:</b> Ant-style patterns with "classpath:" resources are not
141:         * guaranteed to find matching resources if the root package to search is available
142:         * in multiple class path locations. This is because a resource such as<pre>
143:         *     com/mycompany/package1/service-context.xml
144:         * </pre>may be in only one location, but when a path such as<pre>
145:         *     classpath:com/mycompany/**&#47;service-context.xml
146:         * </pre>is used to try to resolve it, the resolver will work off the (first) URL 
147:         * returned by <code>getResource("com/mycompany");</code>. If this base package
148:         * node exists in multiple classloader locations, the actual end resource may
149:         * not be underneath. Therefore, preferably, use "<code>classpath*:<code>" with the same
150:         * Ant-style pattern in such a case, which will search <i>all</i> class path
151:         * locations that contain the root package.
152:         *
153:         * @author Juergen Hoeller
154:         * @author Colin Sampaleanu
155:         * @since 1.0.2
156:         * @see #CLASSPATH_ALL_URL_PREFIX
157:         * @see org.springframework.util.AntPathMatcher
158:         * @see org.springframework.core.io.ResourceLoader#getResource(String)
159:         * @see java.lang.ClassLoader#getResources(String)
160:         */
161:        public class PathMatchingResourcePatternResolver implements 
162:                ResourcePatternResolver {
163:
164:            private static final Log logger = LogFactory
165:                    .getLog(PathMatchingResourcePatternResolver.class);
166:
167:            private final ResourceLoader resourceLoader;
168:
169:            private PathMatcher pathMatcher = new AntPathMatcher();
170:
171:            /**
172:             * Create a new PathMatchingResourcePatternResolver with a DefaultResourceLoader.
173:             * <p>ClassLoader access will happen via the thread context class loader.
174:             * @see org.springframework.core.io.DefaultResourceLoader
175:             */
176:            public PathMatchingResourcePatternResolver() {
177:                this .resourceLoader = new DefaultResourceLoader();
178:            }
179:
180:            /**
181:             * Create a new PathMatchingResourcePatternResolver with a DefaultResourceLoader.
182:             * @param classLoader the ClassLoader to load classpath resources with,
183:             * or <code>null</code> for using the thread context class loader
184:             * @see org.springframework.core.io.DefaultResourceLoader
185:             */
186:            public PathMatchingResourcePatternResolver(ClassLoader classLoader) {
187:                this .resourceLoader = new DefaultResourceLoader(classLoader);
188:            }
189:
190:            /**
191:             * Create a new PathMatchingResourcePatternResolver.
192:             * <p>ClassLoader access will happen via the thread context class loader.
193:             * @param resourceLoader the ResourceLoader to load root directories and
194:             * actual resources with
195:             */
196:            public PathMatchingResourcePatternResolver(
197:                    ResourceLoader resourceLoader) {
198:                Assert.notNull(resourceLoader,
199:                        "ResourceLoader must not be null");
200:                this .resourceLoader = resourceLoader;
201:            }
202:
203:            /**
204:             * Return the ResourceLoader that this pattern resolver works with.
205:             */
206:            public ResourceLoader getResourceLoader() {
207:                return this .resourceLoader;
208:            }
209:
210:            /**
211:             * Return the ClassLoader that this pattern resolver works with
212:             * (never <code>null</code>).
213:             */
214:            public ClassLoader getClassLoader() {
215:                return getResourceLoader().getClassLoader();
216:            }
217:
218:            /**
219:             * Set the PathMatcher implementation to use for this
220:             * resource pattern resolver. Default is AntPathMatcher.
221:             * @see org.springframework.util.AntPathMatcher
222:             */
223:            public void setPathMatcher(PathMatcher pathMatcher) {
224:                Assert.notNull(pathMatcher, "PathMatcher must not be null");
225:                this .pathMatcher = pathMatcher;
226:            }
227:
228:            /**
229:             * Return the PathMatcher that this resource pattern resolver uses.
230:             */
231:            public PathMatcher getPathMatcher() {
232:                return this .pathMatcher;
233:            }
234:
235:            public Resource getResource(String location) {
236:                return getResourceLoader().getResource(location);
237:            }
238:
239:            public Resource[] getResources(String locationPattern)
240:                    throws IOException {
241:                Assert.notNull(locationPattern,
242:                        "Location pattern must not be null");
243:                if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
244:                    // a class path resource (multiple resources for same name possible)
245:                    if (getPathMatcher().isPattern(
246:                            locationPattern.substring(CLASSPATH_ALL_URL_PREFIX
247:                                    .length()))) {
248:                        // a class path resource pattern
249:                        return findPathMatchingResources(locationPattern);
250:                    } else {
251:                        // all class path resources with the given name
252:                        return findAllClassPathResources(locationPattern
253:                                .substring(CLASSPATH_ALL_URL_PREFIX.length()));
254:                    }
255:                } else {
256:                    // Only look for a pattern after a prefix here
257:                    // (to not get fooled by a pattern symbol in a strange prefix).
258:                    int prefixEnd = locationPattern.indexOf(":") + 1;
259:                    if (getPathMatcher().isPattern(
260:                            locationPattern.substring(prefixEnd))) {
261:                        // a file pattern
262:                        return findPathMatchingResources(locationPattern);
263:                    } else {
264:                        // a single resource with the given name
265:                        return new Resource[] { getResourceLoader()
266:                                .getResource(locationPattern) };
267:                    }
268:                }
269:            }
270:
271:            /**
272:             * Find all class location resources with the given location via the ClassLoader.
273:             * @param location the absolute path within the classpath
274:             * @return the result as Resource array
275:             * @throws IOException in case of I/O errors
276:             * @see java.lang.ClassLoader#getResources
277:             * @see #convertClassLoaderURL
278:             */
279:            protected Resource[] findAllClassPathResources(String location)
280:                    throws IOException {
281:                String path = location;
282:                if (path.startsWith("/")) {
283:                    path = path.substring(1);
284:                }
285:                Enumeration resourceUrls = getClassLoader().getResources(path);
286:                Set result = new LinkedHashSet(16);
287:                while (resourceUrls.hasMoreElements()) {
288:                    URL url = (URL) resourceUrls.nextElement();
289:                    result.add(convertClassLoaderURL(url));
290:                }
291:                return (Resource[]) result.toArray(new Resource[result.size()]);
292:            }
293:
294:            /**
295:             * Convert the given URL as returned from the ClassLoader into a Resource object.
296:             * <p>The default implementation simply creates a UrlResource instance.
297:             * @param url a URL as returned from the ClassLoader
298:             * @return the corresponding Resource object
299:             * @see java.lang.ClassLoader#getResources
300:             * @see org.springframework.core.io.Resource
301:             */
302:            protected Resource convertClassLoaderURL(URL url) {
303:                return new UrlResource(url);
304:            }
305:
306:            /**
307:             * Find all resources that match the given location pattern via the
308:             * Ant-style PathMatcher. Supports resources in jar files and zip files
309:             * and in the file system.
310:             * @param locationPattern the location pattern to match
311:             * @return the result as Resource array
312:             * @throws IOException in case of I/O errors
313:             * @see #doFindPathMatchingJarResources
314:             * @see #doFindPathMatchingFileResources
315:             * @see org.springframework.util.PathMatcher
316:             */
317:            protected Resource[] findPathMatchingResources(
318:                    String locationPattern) throws IOException {
319:                String rootDirPath = determineRootDir(locationPattern);
320:                String subPattern = locationPattern.substring(rootDirPath
321:                        .length());
322:                Resource[] rootDirResources = getResources(rootDirPath);
323:                Set result = new LinkedHashSet(16);
324:                for (int i = 0; i < rootDirResources.length; i++) {
325:                    Resource rootDirResource = rootDirResources[i];
326:                    if (isJarResource(rootDirResource)) {
327:                        result.addAll(doFindPathMatchingJarResources(
328:                                rootDirResource, subPattern));
329:                    } else {
330:                        result.addAll(doFindPathMatchingFileResources(
331:                                rootDirResource, subPattern));
332:                    }
333:                }
334:                if (logger.isDebugEnabled()) {
335:                    logger.debug("Resolved location pattern ["
336:                            + locationPattern + "] to resources " + result);
337:                }
338:                return (Resource[]) result.toArray(new Resource[result.size()]);
339:            }
340:
341:            /**
342:             * Determine the root directory for the given location.
343:             * <p>Used for determining the starting point for file matching,
344:             * resolving the root directory location to a <code>java.io.File</code>
345:             * and passing it into <code>retrieveMatchingFiles</code>, with the
346:             * remainder of the location as pattern.
347:             * <p>Will return "/WEB-INF" for the pattern "/WEB-INF/*.xml",
348:             * for example.
349:             * @param location the location to check
350:             * @return the part of the location that denotes the root directory
351:             * @see #retrieveMatchingFiles
352:             */
353:            protected String determineRootDir(String location) {
354:                int prefixEnd = location.indexOf(":") + 1;
355:                int rootDirEnd = location.length();
356:                while (rootDirEnd > prefixEnd
357:                        && getPathMatcher().isPattern(
358:                                location.substring(prefixEnd, rootDirEnd))) {
359:                    rootDirEnd = location.lastIndexOf('/', rootDirEnd - 2) + 1;
360:                }
361:                if (rootDirEnd == 0) {
362:                    rootDirEnd = prefixEnd;
363:                }
364:                return location.substring(0, rootDirEnd);
365:            }
366:
367:            /**
368:             * Return whether the given resource handle indicates a jar resource
369:             * that the <code>doFindPathMatchingJarResources</code> method can handle.
370:             * <p>The default implementation checks against the URL protocols
371:             * "jar", "zip" and "wsjar" (the latter are used by BEA WebLogic Server
372:             * and IBM WebSphere, respectively, but can be treated like jar files).
373:             * @param resource the resource handle to check
374:             * (usually the root directory to start path matching from)
375:             * @see #doFindPathMatchingJarResources
376:             * @see org.springframework.util.ResourceUtils#isJarURL
377:             */
378:            protected boolean isJarResource(Resource resource)
379:                    throws IOException {
380:                return ResourceUtils.isJarURL(resource.getURL());
381:            }
382:
383:            /**
384:             * Find all resources in jar files that match the given location pattern
385:             * via the Ant-style PathMatcher.
386:             * @param rootDirResource the root directory as Resource
387:             * @param subPattern the sub pattern to match (below the root directory)
388:             * @return the Set of matching Resource instances
389:             * @throws IOException in case of I/O errors
390:             * @see java.net.JarURLConnection
391:             * @see org.springframework.util.PathMatcher
392:             */
393:            protected Set doFindPathMatchingJarResources(
394:                    Resource rootDirResource, String subPattern)
395:                    throws IOException {
396:                URLConnection con = rootDirResource.getURL().openConnection();
397:                JarFile jarFile = null;
398:                boolean newJarFile = false;
399:                String jarFileUrl = null;
400:                String rootEntryPath = null;
401:
402:                if (con instanceof  JarURLConnection) {
403:                    // Should usually be the case for traditional JAR files.
404:                    JarURLConnection jarCon = (JarURLConnection) con;
405:                    jarFile = jarCon.getJarFile();
406:                    jarFileUrl = jarCon.getJarFileURL().toExternalForm();
407:                    JarEntry jarEntry = jarCon.getJarEntry();
408:                    rootEntryPath = (jarEntry != null ? jarEntry.getName() : "");
409:                } else {
410:                    // No JarURLConnection -> need to resort to URL file parsing.
411:                    // We'll assume URLs of the format "jar:path!/entry", with the protocol
412:                    // being arbitrary as long as following the entry format.
413:                    // We'll also handle paths with and without leading "file:" prefix.
414:                    String urlFile = rootDirResource.getURL().getFile();
415:                    int separatorIndex = urlFile
416:                            .indexOf(ResourceUtils.JAR_URL_SEPARATOR);
417:                    jarFileUrl = urlFile.substring(0, separatorIndex);
418:                    if (jarFileUrl.startsWith(ResourceUtils.FILE_URL_PREFIX)) {
419:                        jarFileUrl = jarFileUrl
420:                                .substring(ResourceUtils.FILE_URL_PREFIX
421:                                        .length());
422:                    }
423:                    jarFile = new JarFile(jarFileUrl);
424:                    newJarFile = true;
425:                    jarFileUrl = ResourceUtils.FILE_URL_PREFIX + jarFileUrl;
426:                    rootEntryPath = urlFile.substring(separatorIndex
427:                            + ResourceUtils.JAR_URL_SEPARATOR.length());
428:                }
429:
430:                try {
431:                    if (logger.isDebugEnabled()) {
432:                        logger
433:                                .debug("Looking for matching resources in jar file ["
434:                                        + jarFileUrl + "]");
435:                    }
436:                    if (!"".equals(rootEntryPath)
437:                            && !rootEntryPath.endsWith("/")) {
438:                        // Root entry path must end with slash to allow for proper matching.
439:                        // The Sun JRE does not return a slash here, but BEA JRockit does.
440:                        rootEntryPath = rootEntryPath + "/";
441:                    }
442:                    Set result = new LinkedHashSet(8);
443:                    for (Enumeration entries = jarFile.entries(); entries
444:                            .hasMoreElements();) {
445:                        JarEntry entry = (JarEntry) entries.nextElement();
446:                        String entryPath = entry.getName();
447:                        if (entryPath.startsWith(rootEntryPath)) {
448:                            String relativePath = entryPath
449:                                    .substring(rootEntryPath.length());
450:                            if (getPathMatcher()
451:                                    .match(subPattern, relativePath)) {
452:                                result.add(rootDirResource
453:                                        .createRelative(relativePath));
454:                            }
455:                        }
456:                    }
457:                    return result;
458:                } finally {
459:                    // Close jar file, but only if freshly obtained -
460:                    // not from JarURLConnection, which might cache the file reference.
461:                    if (newJarFile) {
462:                        jarFile.close();
463:                    }
464:                }
465:            }
466:
467:            /**
468:             * Find all resources in the file system that match the given location pattern
469:             * via the Ant-style PathMatcher.
470:             * @param rootDirResource the root directory as Resource
471:             * @param subPattern the sub pattern to match (below the root directory)
472:             * @return the Set of matching Resource instances
473:             * @throws IOException in case of I/O errors
474:             * @see #retrieveMatchingFiles
475:             * @see org.springframework.util.PathMatcher
476:             */
477:            protected Set doFindPathMatchingFileResources(
478:                    Resource rootDirResource, String subPattern)
479:                    throws IOException {
480:                File rootDir = null;
481:                try {
482:                    rootDir = rootDirResource.getFile().getAbsoluteFile();
483:                } catch (IOException ex) {
484:                    if (logger.isDebugEnabled()) {
485:                        logger
486:                                .debug(
487:                                        "Cannot search for matching files underneath "
488:                                                + rootDirResource
489:                                                + " because it does not correspond to a directory in the file system",
490:                                        ex);
491:                    }
492:                    return Collections.EMPTY_SET;
493:                }
494:                return doFindMatchingFileSystemResources(rootDir, subPattern);
495:            }
496:
497:            /**
498:             * Find all resources in the file system that match the given location pattern
499:             * via the Ant-style PathMatcher.
500:             * @param rootDir the root directory in the file system
501:             * @param subPattern the sub pattern to match (below the root directory)
502:             * @return the Set of matching Resource instances
503:             * @throws IOException in case of I/O errors
504:             * @see #retrieveMatchingFiles
505:             * @see org.springframework.util.PathMatcher
506:             */
507:            protected Set doFindMatchingFileSystemResources(File rootDir,
508:                    String subPattern) throws IOException {
509:                if (logger.isDebugEnabled()) {
510:                    logger
511:                            .debug("Looking for matching resources in directory tree ["
512:                                    + rootDir.getPath() + "]");
513:                }
514:                Set matchingFiles = retrieveMatchingFiles(rootDir, subPattern);
515:                Set result = new LinkedHashSet(matchingFiles.size());
516:                for (Iterator it = matchingFiles.iterator(); it.hasNext();) {
517:                    File file = (File) it.next();
518:                    result.add(new FileSystemResource(file));
519:                }
520:                return result;
521:            }
522:
523:            /**
524:             * Retrieve files that match the given path pattern,
525:             * checking the given directory and its subdirectories.
526:             * @param rootDir the directory to start from
527:             * @param pattern the pattern to match against,
528:             * relative to the root directory
529:             * @return the Set of matching File instances
530:             * @throws IOException if directory contents could not be retrieved
531:             */
532:            protected Set retrieveMatchingFiles(File rootDir, String pattern)
533:                    throws IOException {
534:                if (!rootDir.isDirectory()) {
535:                    throw new IllegalArgumentException("Resource path ["
536:                            + rootDir + "] does not denote a directory");
537:                }
538:                String fullPattern = StringUtils.replace(rootDir
539:                        .getAbsolutePath(), File.separator, "/");
540:                if (!pattern.startsWith("/")) {
541:                    fullPattern += "/";
542:                }
543:                fullPattern = fullPattern
544:                        + StringUtils.replace(pattern, File.separator, "/");
545:                Set result = new LinkedHashSet(8);
546:                doRetrieveMatchingFiles(fullPattern, rootDir, result);
547:                return result;
548:            }
549:
550:            /**
551:             * Recursively retrieve files that match the given pattern,
552:             * adding them to the given result list.
553:             * @param fullPattern the pattern to match against,
554:             * with preprended root directory path
555:             * @param dir the current directory
556:             * @param result the Set of matching File instances to add to
557:             * @throws IOException if directory contents could not be retrieved
558:             */
559:            protected void doRetrieveMatchingFiles(String fullPattern,
560:                    File dir, Set result) throws IOException {
561:                if (logger.isDebugEnabled()) {
562:                    logger.debug("Searching directory ["
563:                            + dir.getAbsolutePath()
564:                            + "] for files matching pattern [" + fullPattern
565:                            + "]");
566:                }
567:                File[] dirContents = dir.listFiles();
568:                if (dirContents == null) {
569:                    throw new IOException(
570:                            "Could not retrieve contents of directory ["
571:                                    + dir.getAbsolutePath() + "]");
572:                }
573:                for (int i = 0; i < dirContents.length; i++) {
574:                    File content = dirContents[i];
575:                    String currPath = StringUtils.replace(content
576:                            .getAbsolutePath(), File.separator, "/");
577:                    if (content.isDirectory()
578:                            && getPathMatcher().matchStart(fullPattern,
579:                                    currPath + "/")) {
580:                        doRetrieveMatchingFiles(fullPattern, content, result);
581:                    }
582:                    if (getPathMatcher().match(fullPattern, currPath)) {
583:                        result.add(content);
584:                    }
585:                }
586:            }
587:
588:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.