001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package org.apache.geronimo.kernel.classloader;
018    
019    import java.io.*;
020    import java.net.MalformedURLException;
021    import java.net.URL;
022    import java.util.jar.JarEntry;
023    import java.util.jar.JarFile;
024    import java.util.jar.JarInputStream;
025    import java.util.jar.Manifest;
026    import java.util.zip.ZipException;
027    
028    /**
029     * @version $Rev: 500995 $ $Date: 2007-01-29 05:15:23 -0500 (Mon, 29 Jan 2007) $
030     */
031    public class JarResourceLocation extends AbstractUrlResourceLocation {
032        private JarFile jarFile;
033        private byte content[];
034    
035        public JarResourceLocation(URL codeSource, File cacheFile) throws IOException {
036            super(codeSource);
037            try {
038                jarFile = new JarFile(cacheFile);
039            } catch (ZipException ze) {
040                // We get this exception on windows when the
041                // path to the jar file gets too long (Bug ID: 6374379)
042                InputStream is = null;
043                try {
044                    is = new FileInputStream(cacheFile);
045                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
046                    byte[] buffer = new byte[2048];
047                    int bytesRead = -1;
048                    while ((bytesRead = is.read(buffer)) != -1) {
049                        baos.write(buffer, 0, bytesRead);
050                    }
051                    this.content = baos.toByteArray();
052                } finally {
053                    if (is != null) {
054                        is.close();
055                    }
056                }
057            }
058        }
059    
060        public ResourceHandle getResourceHandle(String resourceName) {
061            if (jarFile != null) {
062                JarEntry jarEntry = jarFile.getJarEntry(resourceName);
063                if (jarEntry != null) {
064                    try {
065                        URL url = new URL(getCodeSource(), resourceName);
066                        return new JarResourceHandle(jarFile, jarEntry, getCodeSource());
067                    } catch (MalformedURLException e) {
068                    }
069                }
070            } else {
071                try {
072                    final JarInputStream is = new JarInputStream(new ByteArrayInputStream(this.content));
073                    JarEntry jarEntry = null;
074                    while ((jarEntry = is.getNextJarEntry()) != null) {
075                        if (jarEntry.getName().equals(resourceName)) {
076                            try {
077                                URL url = new URL(getCodeSource(), resourceName);
078                                final JarEntry jarEntry2 = jarEntry;
079                                return new JarEntryResourceHandle(jarEntry2, is);
080                            } catch (MalformedURLException e) {
081                            }
082                        }
083                    }
084                } catch (IOException e) {
085                }
086            }
087            return null;
088        }
089    
090        public Manifest getManifest() throws IOException {
091            if (jarFile != null) {
092                return jarFile.getManifest();
093            } else {
094                try {
095                    JarInputStream is = new JarInputStream(new ByteArrayInputStream(this.content));
096                    return is.getManifest();
097                } catch (IOException e) {
098                }
099            }
100            return null;
101        }
102    
103        public void close() {
104            if (jarFile != null) {
105                IoUtil.close(jarFile);
106            }
107        }
108    
109        private class JarEntryResourceHandle extends AbstractResourceHandle {
110            private final JarEntry jarEntry2;
111            private final JarInputStream is;
112    
113            public JarEntryResourceHandle(JarEntry jarEntry2, JarInputStream is) {
114                this.jarEntry2 = jarEntry2;
115                this.is = is;
116            }
117    
118            public String getName() {
119                return jarEntry2.getName();
120            }
121    
122            public URL getUrl() {
123                try {
124                    return new URL("jar", "", -1, getCodeSource() + "!/" + jarEntry2.getName());
125                } catch (MalformedURLException e) {
126                    throw new RuntimeException(e);
127                }
128            }
129    
130            public boolean isDirectory() {
131                return jarEntry2.isDirectory();
132            }
133    
134            public URL getCodeSourceUrl() {
135                return getCodeSource();
136            }
137    
138            public InputStream getInputStream() throws IOException {
139                return is;
140            }
141    
142            public int getContentLength() {
143                return (int) jarEntry2.getSize();
144            }
145        }
146    }