001: /*
002: * Janino - An embedded Java[TM] compiler
003: *
004: * Copyright (c) 2001-2007, Arno Unkrig
005: * All rights reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: * 2. Redistributions in binary form must reproduce the above
014: * copyright notice, this list of conditions and the following
015: * disclaimer in the documentation and/or other materials
016: * provided with the distribution.
017: * 3. The name of the author may not be used to endorse or promote
018: * products derived from this software without specific prior
019: * written permission.
020: *
021: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
022: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
023: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
024: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
025: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
026: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
027: * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
028: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
029: * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
030: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
031: * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
032: */
033:
034: package org.codehaus.janino.util.resource;
035:
036: import java.io.*;
037: import java.util.*;
038: import java.util.zip.*;
039:
040: import org.codehaus.janino.util.iterator.*;
041:
042: /**
043: * A {@link org.codehaus.janino.util.resource.ResourceFinder} that finds its resources along a "path"
044: * consisting of JAR file names, ZIP file names, and directory names.
045: * @see org.codehaus.janino.util.resource.ZipFileResourceFinder
046: * @see org.codehaus.janino.util.resource.DirectoryResourceFinder
047: */
048: public class PathResourceFinder extends LazyMultiResourceFinder {
049:
050: /**
051: * @param entries The entries of the "path"
052: */
053: public PathResourceFinder(final File[] entries) {
054: super (PathResourceFinder.createIterator(Arrays.asList(entries)
055: .iterator()));
056: }
057:
058: /**
059: * @param entries The entries of the "path" (type must be {@link File})
060: */
061: public PathResourceFinder(Iterator entries) {
062: super (entries);
063: }
064:
065: /**
066: * @param path A java-like path, i.e. a "path separator"-separated list of entries.
067: */
068: public PathResourceFinder(String path) {
069: this (PathResourceFinder.parsePath(path));
070: }
071:
072: private static Iterator createIterator(final Iterator entries) {
073: return new TransformingIterator(entries) {
074: protected Object transform(Object o) {
075: return PathResourceFinder
076: .createResourceFinder((File) o);
077: }
078: };
079: }
080:
081: /**
082: * Break a given string up by the system-dependent path-separator character (on UNIX systems,
083: * this character is ':'; on Microsoft Windows systems it is ';'). Empty components are
084: * ignored.
085: * <p>
086: * UNIX Examples:
087: * <dl>
088: * <dt>A:B:C <dd>A, B, C
089: * <dt>::B: <dd>B
090: * <dt>:A <dd>A
091: * <dt>(Empty string) <dd>(Zero components)
092: * </dl>
093: *
094: * @see File#pathSeparatorChar
095: */
096: public static File[] parsePath(String s) {
097: int from = 0;
098: List l = new ArrayList(); // File
099: for (;;) {
100: int to = s.indexOf(File.pathSeparatorChar, from);
101: if (to == -1) {
102: if (from != s.length())
103: l.add(new File(s.substring(from)));
104: break;
105: }
106: if (to != from)
107: l.add(new File(s.substring(from, to)));
108: from = to + 1;
109: }
110: return (File[]) l.toArray(new File[l.size()]);
111: }
112:
113: /**
114: * A factory method that creates a Java classpath-style ResourceFinder as
115: * follows:
116: * <table>
117: * <tr><th><code>entry</code></th><th>Returned {@link ResourceFinder}</th></tr>
118: * <tr><td>"*.jar" file</td><td>{@link ZipFileResourceFinder}</td></tr>
119: * <tr><td>"*.zip" file</td><td>{@link ZipFileResourceFinder}</td></tr>
120: * <tr><td>directory</td><td>{@link DirectoryResourceFinder}</td></tr>
121: * <tr><td>any other</td><td>A {@link ResourceFinder} that never finds a resource</td></tr>
122: * </table>
123: * @return a valid {@link ResourceFinder}
124: */
125: private static ResourceFinder createResourceFinder(final File entry) {
126:
127: // ZIP file or JAR file.
128: if ((entry.getName().endsWith(".jar") || entry.getName()
129: .endsWith(".zip"))
130: && entry.isFile()) {
131: try {
132: return new ZipFileResourceFinder(new ZipFile(entry));
133: } catch (IOException e) {
134: return ResourceFinder.EMPTY_RESOURCE_FINDER;
135: }
136: }
137:
138: // Directory.
139: if (entry.isDirectory()) {
140: return new DirectoryResourceFinder(entry);
141: }
142:
143: // Invalid entry.
144: return ResourceFinder.EMPTY_RESOURCE_FINDER;
145: }
146: }
|