jar.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 953 行 · 第 1/2 页
JAVA
953 行
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */package com.caucho.vfs;import com.caucho.loader.EnvironmentLocal;import com.caucho.make.CachedDependency;import com.caucho.util.Alarm;import com.caucho.util.CacheListener;import com.caucho.util.Log;import com.caucho.util.LruCache;import com.caucho.util.L10N;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.lang.ref.SoftReference;import java.security.cert.Certificate;import java.util.*;import java.util.jar.*;import java.util.logging.Level;import java.util.logging.Logger;import java.util.zip.ZipEntry;import java.util.zip.ZipFile;import java.util.zip.ZipInputStream;/** * Jar is a cache around a jar file to avoid scanning through the whole * file on each request. * * <p>When the Jar is created, it scans the file and builds a directory * of the Jar entries. */public class Jar implements CacheListener { private static final Logger log = Log.open(Jar.class); private static final L10N L = new L10N(Jar.class); private static LruCache<Path,Jar> _jarCache; private static EnvironmentLocal<Integer> _jarSize = new EnvironmentLocal<Integer>("caucho.vfs.jar-size"); private Path _backing; private boolean _backingIsFile; private JarDepend _depend; // saved last modified time private long _lastModified; // saved length private long _length; // last time the file was checked private long _lastTime; // cached zip file to read jar entries private SoftReference<JarFile> _jarFileRef; // last time the zip file was modified private long _jarLastModified; private long _jarLength; private Boolean _isSigned; // file to be closed private SoftReference<JarFile> _closeJarFileRef; /** * Creates a new Jar. * * @param path canonical path */ private Jar(Path backing) { if (backing instanceof JarPath) throw new IllegalStateException(); _backing = backing; _backingIsFile = (_backing.getScheme().equals("file") && _backing.canRead()); } /** * Return a Jar for the path. If the backing already exists, return * the old jar. */ static Jar create(Path backing) { if (_jarCache == null) { int size = 256; Integer iSize = _jarSize.get(); if (iSize != null) size = iSize.intValue(); _jarCache = new LruCache<Path,Jar>(size); } Jar jar = _jarCache.get(backing); if (jar == null) { jar = new Jar(backing); jar = _jarCache.putIfNew(backing, jar); } return jar; } /** * Return a Jar for the path. If the backing already exists, return * the old jar. */ static Jar getJar(Path backing) { if (_jarCache != null) { Jar jar = _jarCache.get(backing); return jar; } return null; } /** * Return a Jar for the path. If the backing already exists, return * the old jar. */ public static PersistentDependency createDepend(Path backing) { Jar jar = create(backing); return jar.getDepend(); } /** * Return a Jar for the path. If the backing already exists, return * the old jar. */ public static PersistentDependency createDepend(Path backing, long digest) { Jar jar = create(backing); return new JarDigestDepend(jar.getJarDepend(), digest); } /** * Returns the backing path. */ Path getBacking() { return _backing; } /** * Returns the dependency. */ public PersistentDependency getDepend() { return getJarDepend(); } /** * Returns the dependency. */ private JarDepend getJarDepend() { if (_depend == null || _depend.isModified()) _depend = new JarDepend(new Depend(getBacking())); return _depend; } private boolean isSigned() { Boolean isSigned = _isSigned; if (isSigned != null) return isSigned; try { Manifest manifest = getManifest(); if (manifest == null) { _isSigned = Boolean.FALSE; return false; } Map<String,Attributes> entries = manifest.getEntries(); if (entries == null) { _isSigned = Boolean.FALSE; return false; } for (Attributes attr : entries.values()) { for (Object key : attr.keySet()) { String keyString = String.valueOf(key); if (keyString.contains("Digest")) { _isSigned = Boolean.TRUE; return true; } } } } catch (IOException e) { log.log(Level.FINE, e.toString(), e); } _isSigned = Boolean.FALSE; return false; } /** * Returns true if the entry is a file in the jar. * * @param path the path name inside the jar. */ public Manifest getManifest() throws IOException { Manifest manifest; synchronized (this) { JarFile jarFile = getJarFile(); if (jarFile == null) manifest = null; else manifest = jarFile.getManifest(); } closeJarFile(); return manifest; } /** * Returns any certificates. */ public Certificate []getCertificates(String path) { if (! isSigned()) return null; if (path.length() > 0 && path.charAt(0) == '/') path = path.substring(1); try { if (! _backing.canRead()) return null; JarFile jarFile = new JarFile(_backing.getNativePath()); JarEntry entry; InputStream is = null; try { entry = jarFile.getJarEntry(path); if (entry != null) { is = jarFile.getInputStream(entry); while (is.skip(65536) > 0) { } is.close(); return entry.getCertificates(); } } finally { jarFile.close(); } } catch (IOException e) { log.log(Level.FINE, e.toString(), e); return null; } return null; } /** * Returns true if the entry exists in the jar. * * @param path the path name inside the jar. */ public boolean exists(String path) { // server/249f, server/249g // XXX: facelets vs issue of meta-inf (i.e. lower case) boolean result = false; synchronized (this) { try { ZipEntry entry = getJarEntry(path); result = entry != null; } catch (IOException e) { log.log(Level.FINE, e.toString(), e); } } closeJarFile(); return result; } /** * Returns true if the entry is a directory in the jar. * * @param path the path name inside the jar. */ public boolean isDirectory(String path) { boolean result = false; synchronized (this) { try { ZipEntry entry = getJarEntry(path); result = entry != null && entry.isDirectory(); } catch (IOException e) { log.log(Level.FINE, e.toString(), e); } } closeJarFile(); return result; } /** * Returns true if the entry is a file in the jar. * * @param path the path name inside the jar. */ public boolean isFile(String path) { boolean result = false; synchronized (this) { try { ZipEntry entry = getJarEntry(path); result = entry != null && ! entry.isDirectory(); } catch (IOException e) { log.log(Level.FINE, e.toString(), e); } } closeJarFile(); return result; } /** * Returns the length of the entry in the jar file. * * @param path full path to the jar entry * @return the length of the entry */ public long getLastModified(String path) { long result = -1; synchronized (this) { try { ZipEntry entry = getJarEntry(path); result = entry != null ? entry.getTime() : -1; } catch (IOException e) { log.log(Level.FINE, e.toString(), e); } } closeJarFile(); return result; } /** * Returns the length of the entry in the jar file. * * @param path full path to the jar entry * @return the length of the entry */ public long getLength(String path) { long result = -1; synchronized (this) { try { ZipEntry entry = getJarEntry(path); result = entry != null ? entry.getSize() : -1; } catch (IOException e) { log.log(Level.FINE, e.toString(), e); } } closeJarFile(); return result; } /** * Readable if the jar is readable and the path refers to a file. */ public boolean canRead(String path) { boolean result = false; synchronized (this) { try { ZipEntry entry = getJarEntry(path); result = entry != null && ! entry.isDirectory(); } catch (IOException e) { log.log(Level.FINE, e.toString(), e); return false; } } closeJarFile(); return result; } /** * Can't write to jars. */ public boolean canWrite(String path) { return false; } /** * Lists all the files in this directory. */ public String []list(String path) throws IOException { // XXX: return new String[0]; } /** * Opens a stream to an entry in the jar. * * @param path relative path into the jar. */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?