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: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
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 }