001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.vfs;
031:
032: import com.caucho.util.LruCache;
033:
034: import java.io.IOException;
035: import java.security.cert.Certificate;
036: import java.util.Map;
037: import java.util.jar.Manifest;
038:
039: /**
040: * A filesystem for .jar files.
041: */
042: public class JarPath extends FilesystemPath {
043: private static LruCache<Path, JarPath> _jarCache = new LruCache<Path, JarPath>(
044: 256);
045:
046: private Path _backing;
047:
048: /**
049: * Creates a new jar path for the specific file
050: *
051: * @param root the root of this jar
052: * @param userPath the path specified by the user in the lookup()
053: * @param path the normalized path
054: * @param jarFile the underlying jar
055: */
056: protected JarPath(FilesystemPath root, String userPath,
057: String path, Path backing) {
058: super (root, userPath, path);
059:
060: if (_root == null)
061: _root = this ;
062:
063: if (backing instanceof JarPath)
064: throw new IllegalStateException(backing.toString()
065: + " is already a jar");
066:
067: _backing = backing;
068: }
069:
070: /**
071: * Creates a new root Jar path.
072: */
073: public static JarPath create(Path backing) {
074: if (backing instanceof JarPath)
075: return (JarPath) backing;
076:
077: JarPath path = _jarCache.get(backing);
078:
079: if (path == null) {
080: path = new JarPath(null, "/", "/", backing);
081: _jarCache.put(backing, path);
082: }
083:
084: return path;
085: }
086:
087: public Path fsWalk(String userPath, Map<String, Object> attributes,
088: String path) {
089: if ("/".equals(userPath) && "/".equals(path))
090: return _root;
091: else
092: return new JarPath(_root, userPath, path, _backing);
093: }
094:
095: /**
096: * Returns the scheme (jar)
097: */
098: public String getScheme() {
099: return "jar";
100: }
101:
102: @Override
103: public boolean isPathCacheable() {
104: return true;
105: }
106:
107: /**
108: * Returns the full url.
109: *
110: * <p>jar:<container-url>!/entry-path
111: */
112: public String getURL() {
113: String path = getFullPath();
114:
115: return getScheme() + ":" + getContainer().getURL() + "!" + path;
116: }
117:
118: /**
119: * Returns the underlying file below the jar.
120: */
121: public Path getContainer() {
122: return _backing;
123: }
124:
125: /**
126: * Returns any signing certificates.
127: */
128: @Override
129: public Certificate[] getCertificates() {
130: return getJar().getCertificates(getPath());
131: }
132:
133: /**
134: * Returns true if the entry exists in the jar file.
135: */
136: public boolean exists() {
137: return getJar().exists(getPath());
138: }
139:
140: /**
141: * Returns true if the entry is a directory in the jar file.
142: */
143: public boolean isDirectory() {
144: return getJar().isDirectory(getPath());
145: }
146:
147: /**
148: * Returns true if the entry is a file in the jar file.
149: */
150: public boolean isFile() {
151: return getJar().isFile(getPath());
152: }
153:
154: public long getLength() {
155: return getJar().getLength(getPath());
156: }
157:
158: public long getLastModified() {
159: return getJar().getLastModified(getPath());
160: }
161:
162: public boolean canRead() {
163: return getJar().canRead(getPath());
164: }
165:
166: public boolean canWrite() {
167: return getJar().canWrite(getPath());
168: }
169:
170: /**
171: * Returns a list of the directories in the jar.
172: */
173: public String[] list() throws IOException {
174: return getJar().list(getPath());
175: }
176:
177: /**
178: * Returns the manifest.
179: */
180: public Manifest getManifest() throws IOException {
181: return getJar().getManifest();
182: }
183:
184: /**
185: * Returns the dependency checker from the jar.
186: */
187: public PersistentDependency getDepend() {
188: return getJar().getDepend();
189: }
190:
191: public StreamImpl openReadImpl() throws IOException {
192: return getJar().openReadImpl(this );
193: }
194:
195: protected Jar getJar() {
196: return Jar.create(_backing);
197: }
198:
199: public void closeJar() {
200: Jar jar = Jar.getJar(_backing);
201:
202: if (jar != null)
203: jar.close();
204: }
205:
206: public String toString() {
207: return "jar:(" + _backing + ")" + getPath();
208: }
209:
210: public int hashCode() {
211: return 65531 * getPath().hashCode() + getContainer().hashCode();
212: }
213:
214: /**
215: * Tests for equality.
216: */
217: public boolean equals(Object o) {
218: if (this == o)
219: return true;
220: else if (o == null || !o.getClass().equals(this .getClass()))
221: return false;
222:
223: JarPath jarPath = (JarPath) o;
224:
225: return (_backing.equals(jarPath._backing) && getPath().equals(
226: jarPath.getPath()));
227: }
228: }
|