001: /*
002: * Janino - An embedded Java[TM] compiler
003: *
004: * Copyright (c) 2006, 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 (new EnumerationIterator(new StringTokenizer(path,
070: File.pathSeparator)));
071: }
072:
073: private static Iterator createIterator(final Iterator entries) {
074: return new TransformingIterator(entries) {
075: protected Object transform(Object o) {
076: return PathResourceFinder
077: .createResourceFinder((File) o);
078: }
079: };
080: }
081:
082: /**
083: * Break a given string up by a "separator" string. Empty components are
084: * ignored.
085: * <p>
086: * 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: public static File[] parsePath(String s) {
095: int from = 0;
096: List l = new ArrayList(); // File
097: for (;;) {
098: int to = s.indexOf(File.pathSeparatorChar, from);
099: if (to == -1) {
100: if (from != s.length())
101: l.add(new File(s.substring(from)));
102: break;
103: }
104: if (to != from)
105: l.add(new File(s.substring(from, to)));
106: from = to + 1;
107: }
108: return (File[]) l.toArray(new File[l.size()]);
109: }
110:
111: /**
112: * A factory method that creates a Java classpath-style ResourceFinder as
113: * follows:
114: * <table>
115: * <tr><th><code>entry</code></th><th>Returned {@link ResourceFinder}</th></tr>
116: * <tr><td>"*.jar" file</td><td>{@link ZipFileResourceFinder}</td></tr>
117: * <tr><td>"*.zip" file</td><td>{@link ZipFileResourceFinder}</td></tr>
118: * <tr><td>directory</td><td>{@link DirectoryResourceFinder}</td></tr>
119: * <tr><td>any other</td><td>A {@link ResourceFinder} that never finds a resource</td></tr>
120: * </table>
121: * @return a valid {@link ResourceFinder}
122: */
123: private static ResourceFinder createResourceFinder(final File entry) {
124:
125: // ZIP file or JAR file.
126: if ((entry.getName().endsWith(".jar") || entry.getName()
127: .endsWith(".zip"))
128: && entry.isFile()) {
129: try {
130: return new ZipFileResourceFinder(new ZipFile(entry));
131: } catch (IOException e) {
132: return ResourceFinder.EMPTY_RESOURCE_FINDER;
133: }
134: }
135:
136: // Directory.
137: if (entry.isDirectory()) {
138: return new DirectoryResourceFinder(entry);
139: }
140:
141: // Invalid entry.
142: return ResourceFinder.EMPTY_RESOURCE_FINDER;
143: }
144: }
|