FileDocCategorySizeDatePackage
JarURLConnection.javaAPI DocAndroid 1.5 API15953Wed May 06 22:41:04 BST 2009org.apache.harmony.luni.internal.net.www.protocol.jar

JarURLConnection

public class JarURLConnection extends JarURLConnection
This subclass extends URLConnection.

This class is responsible for connecting and retrieving resources from a Jar file which can be anywhere that can be refered to by an URL.

Fields Summary
static Hashtable
jarCache
InputStream
jarInput
private JarFile
jarFile
private JarEntry
jarEntry
private boolean
closed
ReferenceQueue
cacheQueue
static TreeSet
lru
static int
Limit
Constructors Summary
public JarURLConnection(URL url)

param
url the URL of the JAR
throws
MalformedURLException if the URL is malformed

        super(url);
    
Methods Summary
public static voidcloseCachedFiles()
Closes the cached files.

        Enumeration<CacheEntry<? extends JarFile>> elemEnum = jarCache
                .elements();
        while (elemEnum.hasMoreElements()) {
            try {
                ZipFile zip = elemEnum.nextElement().get();
                if (zip != null) {
                    zip.close();
                }
            } catch (IOException e) {
                // Ignored
            }
        }
    
public voidconnect()

see
java.net.URLConnection#connect()

        jarFileURLConnection = getJarFileURL().openConnection();
        findJarFile(); // ensure the file can be found
        findJarEntry(); // ensure the entry, if any, can be found
        connected = true;
    
private voidfindJarEntry()
Look up the JarEntry of the entry referenced by this URLConnection.

        if (getEntryName() == null) {
            return;
        }
        jarEntry = jarFile.getJarEntry(getEntryName());
        if (jarEntry == null) {
            throw new FileNotFoundException(getEntryName());
        }
    
private voidfindJarFile()
Returns the Jar file refered by this URLConnection

throws
IOException if an IO error occurs while connecting to the resource.

        URL jarFileURL = getJarFileURL();
        if (jarFileURL.getProtocol().equals("file")) { //$NON-NLS-1$
            String fileName = jarFileURL.getFile();
            if(!new File(Util.decode(fileName,false)).exists()){
                // KA026=JAR entry {0} not found in {1}
                throw new FileNotFoundException(Msg.getString("KA026", //$NON-NLS-1$
                        getEntryName(), fileName));
            }
            String host = jarFileURL.getHost();
            if (host != null && host.length() > 0) {
                fileName = "//" + host + fileName; //$NON-NLS-1$
            }
            jarFile = openJarFile(fileName, fileName, false);
            return;
        }

        final String externalForm = jarFileURLConnection.getURL()
                .toExternalForm();
        jarFile = AccessController
                .doPrivileged(new PrivilegedAction<JarFile>() {
                    public JarFile run() {
                        try {
                            return openJarFile(null, externalForm, false);
                        } catch (IOException e) {
                            return null;
                        }
                    }
                });
        if (jarFile != null) {
            return;
        }

        // Build a temp jar file
        final InputStream is = jarFileURLConnection.getInputStream();
        try {
            jarFile = AccessController
                    .doPrivileged(new PrivilegedAction<JarFile>() {
                        public JarFile run() {
                            try {
                                File tempJar = File.createTempFile("hyjar_", //$NON-NLS-1$
                                        ".tmp", null); //$NON-NLS-1$
                                FileOutputStream fos = new FileOutputStream(
                                        tempJar);
                                byte[] buf = new byte[4096];
                                int nbytes = 0;
                                while ((nbytes = is.read(buf)) > -1) {
                                    fos.write(buf, 0, nbytes);
                                }
                                fos.close();
                                String path = tempJar.getPath();
                                return openJarFile(path, externalForm, true);
                            } catch (IOException e) {
                                return null;
                            }
                        }
                    });
        } finally {
            is.close();
        }
        if (jarFile == null) {
            throw new IOException();
        }
    
public java.lang.ObjectgetContent()
Returns the object pointed by this URL. If this URLConnection is pointing to a Jar File (no Jar Entry), this method will return a JarFile If there is a Jar Entry, it will return the object corresponding to the Jar entry content type.

return
a non-null object
throws
IOException if an IO error occured
see
ContentHandler
see
ContentHandlerFactory
see
java.io.IOException
see
#setContentHandlerFactory(ContentHandlerFactory)

        if (!connected) {
            connect();
        }
        // if there is no Jar Entry, return a JarFile
        if (jarEntry == null) {
            return jarFile;
        }
        return super.getContent();
    
public intgetContentLength()
Returns the content length of the resource. Test cases reveal that if the URL is refering to a Jar file, this method returns a content-length returned by URLConnection. If not, it will return -1.

return
the content length

        try {
            if (url.getFile().endsWith("!/")) { //$NON-NLS-1$
                return getJarFileURL().openConnection().getContentLength();
            }
        } catch (IOException e) {
            //Ignored
        }
        return -1;
    
public java.lang.StringgetContentType()
Returns the content type of the resource. Test cases reveal that only if the URL is refering to a Jar file, that this method returns a non-null value - x-java/jar.

return
the content type

        // it could also return "x-java/jar" which jdk returns but here, we get
        // it from the URLConnection
        try {
            if (url.getFile().endsWith("!/")) { //$NON-NLS-1$
                return getJarFileURL().openConnection().getContentType();
            }
        } catch (IOException ioe) {
            // Ignore
        }
        // if there is an Jar Entry, get the content type from the name
        return guessContentTypeFromName(url.getFile());
    
public java.io.InputStreamgetInputStream()
Creates an input stream for reading from this URL Connection.

return
the input stream
throws
IOException if an IO error occurs while connecting to the resource.

        if (closed) {
            throw new IllegalStateException(Msg.getString("KA027"));
        }
        if (!connected) {
            connect();
        }
        if (jarInput != null) {
            return jarInput;
        }
        if (jarEntry == null) {
            throw new IOException(Msg.getString("K00fc")); //$NON-NLS-1$
        }
        return jarInput = new JarURLConnectionInputStream(jarFile
                .getInputStream(jarEntry), jarFile);
    
public java.util.jar.JarEntrygetJarEntry()
Returns the JarEntry of the entry referenced by this URLConnection.

return
java.util.jar.JarEntry the JarEntry referenced
throws
IOException if an IO error occurs while getting the entry

        if (!connected) {
            connect();
        }
        return jarEntry;

    
public java.util.jar.JarFilegetJarFile()
Returns the Jar file refered by this URLConnection

return
the JAR file referenced by this connection
throws
IOException thrown if an IO error occurs while connecting to the resource.

        if (!connected) {
            connect();
        }
        return jarFile;
    
public java.security.PermissiongetPermission()
Returns the permission, in this case the subclass, FilePermission object which represents the permission necessary for this URLConnection to establish the connection.

return
the permission required for this URLConnection.
throws
IOException thrown when an IO exception occurs while creating the permission.

        if (jarFileURLConnection != null) {
            return jarFileURLConnection.getPermission();
        }
        return getJarFileURL().openConnection().getPermission();
    
java.util.jar.JarFileopenJarFile(java.lang.String fileString, java.lang.String key, boolean temp)


        JarFile jar = null;
        if (useCaches) {
            CacheEntry<? extends JarFile> entry;
            while ((entry = (CacheEntry<? extends JarFile>) cacheQueue.poll()) != null) {
                jarCache.remove(entry.key);
            }
            entry = jarCache.get(key);
            if (entry != null) {
                jar = entry.get();
            }
            if (jar == null && fileString != null) {
                int flags = ZipFile.OPEN_READ
                        + (temp ? ZipFile.OPEN_DELETE : 0);
                jar = new JarFile(new File(Util.decode(fileString, false)),
                        true, flags);
                jarCache
                        .put(key, new CacheEntry<JarFile>(jar, key, cacheQueue));
            } else {
                SecurityManager security = System.getSecurityManager();
                if (security != null) {
                    security.checkPermission(getPermission());
                }
                if (temp) {
                    lru.remove(new LRUKey(jar, 0));
                }
            }
        } else if (fileString != null) {
            int flags = ZipFile.OPEN_READ + (temp ? ZipFile.OPEN_DELETE : 0);
            jar = new JarFile(new File(Util.decode(fileString, false)), true,
                    flags);
        }

        if (temp) {
            lru.add(new LRUKey(jar, new Date().getTime()));
            if (lru.size() > Limit) {
                lru.remove(lru.first());
            }
        }
        return jar;