Java tutorial
// ======================================================================== // $Id: JarFileResource.java,v 1.12 2005/08/13 00:01:28 gregwilkins Exp $ // Copyright 1996-2004 Mort Bay Consulting Pty. Ltd. // ------------------------------------------------------------------------ // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ======================================================================== package net.lightbody.bmp.proxy.jetty.util; import net.lightbody.bmp.proxy.jetty.log.LogFactory; import org.apache.commons.logging.Log; import java.io.File; import java.io.IOException; import java.net.JarURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; /* ------------------------------------------------------------ */ class JarFileResource extends JarResource { private static Log log = LogFactory.getLog(JarFileResource.class); transient JarFile _jarFile; transient File _file; transient String[] _list; transient JarEntry _entry; transient boolean _directory; transient String _jarUrl; transient String _path; transient boolean _exists; /* -------------------------------------------------------- */ JarFileResource(URL url) { super(url); } /* ------------------------------------------------------------ */ public synchronized void release() { _list = null; _entry = null; _file = null; _jarFile = null; super.release(); } /* ------------------------------------------------------------ */ protected boolean checkConnection() { try { super.checkConnection(); } finally { if (_jarConnection == null) { _entry = null; _file = null; _jarFile = null; _list = null; } } return _jarFile != null; } /* ------------------------------------------------------------ */ protected void newConnection() throws IOException { super.newConnection(); _entry = null; _file = null; _jarFile = null; _list = null; int sep = _urlString.indexOf("!/"); _jarUrl = _urlString.substring(0, sep + 2); _path = _urlString.substring(sep + 2); if (_path.length() == 0) _path = null; _jarFile = _jarConnection.getJarFile(); _file = new File(_jarFile.getName()); } /* ------------------------------------------------------------ */ /** * Returns true if the respresenetd resource exists. */ public boolean exists() { if (_exists) return true; if (_urlString.endsWith("!/")) { String file_url = _urlString.substring(4, _urlString.length() - 2); try { return newResource(file_url).exists(); } catch (Exception e) { LogSupport.ignore(log, e); return false; } } boolean check = checkConnection(); // Is this a root URL? if (_jarUrl != null && _path == null) { // Then if it exists it is a directory _directory = check; return true; } else { // Can we find a file for it? JarFile jarFile = null; if (check) // Yes jarFile = _jarFile; else { // No - so lets look if the root entry exists. try { jarFile = ((JarURLConnection) ((new URL(_jarUrl)).openConnection())).getJarFile(); } catch (Exception e) { LogSupport.ignore(log, e); } } // Do we need to look more closely? if (jarFile != null && _entry == null && !_directory) { // OK - we have a JarFile, lets look at the entries for our path Enumeration e = jarFile.entries(); while (e.hasMoreElements()) { JarEntry entry = (JarEntry) e.nextElement(); String name = entry.getName().replace('\\', '/'); // Do we have a match if (name.equals(_path)) { _entry = entry; // Is the match a directory _directory = _path.endsWith("/"); break; } else if (_path.endsWith("/")) { if (name.startsWith(_path)) { _directory = true; break; } } else if (name.startsWith(_path) && name.length() > _path.length() && name.charAt(_path.length()) == '/') { _directory = true; break; } } } } _exists = (_directory || _entry != null); return _exists; } /* ------------------------------------------------------------ */ /** * Returns true if the respresenetd resource is a container/directory. * If the resource is not a file, resources ending with "/" are * considered directories. */ public boolean isDirectory() { return _urlString.endsWith("/") || exists() && _directory; } /* ------------------------------------------------------------ */ /** * Returns the last modified time */ public long lastModified() { if (checkConnection() && _file != null) return _file.lastModified(); return -1; } /* ------------------------------------------------------------ */ public synchronized String[] list() { if (isDirectory() && _list == null) { ArrayList list = new ArrayList(32); checkConnection(); JarFile jarFile = _jarFile; if (jarFile == null) { try { jarFile = ((JarURLConnection) ((new URL(_jarUrl)).openConnection())).getJarFile(); } catch (Exception e) { LogSupport.ignore(log, e); } } Enumeration e = jarFile.entries(); String dir = _urlString.substring(_urlString.indexOf("!/") + 2); while (e.hasMoreElements()) { JarEntry entry = (JarEntry) e.nextElement(); String name = entry.getName().replace('\\', '/'); if (!name.startsWith(dir) || name.length() == dir.length()) continue; String listName = name.substring(dir.length()); int dash = listName.indexOf('/'); if (dash >= 0) { listName = listName.substring(0, dash + 1); if (list.contains(listName)) continue; } list.add(listName); } _list = new String[list.size()]; list.toArray(_list); } return _list; } /* ------------------------------------------------------------ */ /** * Return the length of the resource */ public long length() { if (isDirectory()) return -1; if (_entry != null) return _entry.getSize(); return -1; } /* ------------------------------------------------------------ */ /** Encode according to this resource type. * File URIs are not encoded. * @param uri URI to encode. * @return The uri unchanged. */ public String encode(String uri) { return uri; } }