blob: 0f3fdbfbcfc1c82d8a52b768d74a92db7fb3a62a [file] [log] [blame]
Richard S. Hall930fecc2005-08-16 18:33:34 +00001/*
2 * Copyright 2005 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
Richard S. Hall5a031592005-08-19 19:53:58 +000017package org.apache.felix.moduleloader;
Richard S. Hall930fecc2005-08-16 18:33:34 +000018
19import java.io.*;
20import java.util.jar.JarFile;
21import java.util.zip.ZipEntry;
22
23/**
24 * <p>
25 * This class implements a <tt>ResourceSource</tt> for retrieving resources
26 * from a JAR file. The approach used by this implementation is to defer
27 * opening the JAR file until a request for a resource is made.
28 * </p>
Richard S. Hall5a031592005-08-19 19:53:58 +000029 * @see org.apache.felix.moduleloader.ResourceSource
Richard S. Hall930fecc2005-08-16 18:33:34 +000030**/
31public class JarResourceSource implements ResourceSource
32{
33 private static final int BUFSIZE = 4096;
34
35 private File m_file = null;
36 private JarFile m_jarFile = null;
37 private boolean m_opened = false;
38
39 /**
40 * <p>
41 * Constructs an instance using the specified file name as the source
42 * of the JAR file.
43 * </p>
44 * @param fileName the name of the JAR file to be used as the source.
45 **/
46 public JarResourceSource(String fileName)
47 {
48 m_file = new File(fileName);
49 }
50
51 /**
52 * <p>
53 * Constructs an instance using the specified file as the source
54 * of the JAR file.
55 * </p>
56 * @param file the JAR file to be used as the source.
57 **/
58 public JarResourceSource(File file)
59 {
60 m_file = file;
61 }
62
63 /**
64 * <p>
65 * Closes the JAR file if it has not already been closed.
66 * <p>
67 **/
68 protected void finalize()
69 {
70 if (m_jarFile != null)
71 {
72 try {
73 m_jarFile.close();
74 } catch (IOException ex) {
75 // Not much we can do, so ignore it.
76 }
77 }
78 }
79
80 /**
81 * <p>
82 * This method initializes the resource source. Since opening
83 * the JAR file is deferred until a request for a resource is
84 * actually made, this method really only sets a flag indicating
85 * that the resource source has been initialized.
86 * <p>
87 **/
88 public void open()
89 {
90 m_opened = true;
91 }
92
93 /**
94 * <p>
95 * This method deinitializes the resource source by closing
96 * the associated JAR file if it is open.
97 * <p>
98 **/
99 public synchronized void close()
100 {
101 try {
102 if (m_jarFile != null)
103 {
104 m_jarFile.close();
105 }
106 } catch (Exception ex) {
107 System.err.println("JarResourceSource: " + ex);
108 }
109
110 m_jarFile = null;
111 m_opened = false;
112 }
113
114 // JavaDoc comments are copied from ResourceSource.
115 public synchronized boolean hasResource(String name) throws IllegalStateException
116 {
117 if (!m_opened)
118 {
119 throw new IllegalStateException("JarResourceSource is not open");
120 }
121
122 // Open JAR file if not already opened.
123 if (m_jarFile == null)
124 {
125 try {
126 openJarFile();
127 } catch (IOException ex) {
128 System.err.println("JarResourceSource: " + ex);
129 return false;
130 }
131 }
132
133 try {
134 ZipEntry ze = m_jarFile.getEntry(name);
135 return ze != null;
136 } catch (Exception ex) {
137 return false;
138 } finally {
139 }
140 }
141
142 // JavaDoc comments are copied from ResourceSource.
143 public synchronized byte[] getBytes(String name) throws IllegalStateException
144 {
145 if (!m_opened)
146 {
147 throw new IllegalStateException("JarResourceSource is not open");
148 }
149
150 // Open JAR file if not already opened.
151 if (m_jarFile == null)
152 {
153 try {
154 openJarFile();
155 } catch (IOException ex) {
156 System.err.println("JarResourceSource: " + ex);
157 return null;
158 }
159 }
160
161 // Get the embedded resource.
162 InputStream is = null;
163 ByteArrayOutputStream baos = null;
164
165 try {
166 ZipEntry ze = m_jarFile.getEntry(name);
167 if (ze == null)
168 {
169 return null;
170 }
171 is = m_jarFile.getInputStream(ze);
172 if (is == null)
173 {
174 return null;
175 }
176 baos = new ByteArrayOutputStream(BUFSIZE);
177 byte[] buf = new byte[BUFSIZE];
178 int n = 0;
179 while ((n = is.read(buf, 0, buf.length)) >= 0)
180 {
181 baos.write(buf, 0, n);
182 }
183 return baos.toByteArray();
184
185 } catch (Exception ex) {
186 return null;
187 } finally {
188 try {
189 if (baos != null) baos.close();
190 } catch (Exception ex) {
191 }
192 try {
193 if (is != null) is.close();
194 } catch (Exception ex) {
195 }
196 }
197 }
198
199 private void openJarFile() throws IOException
200 {
201 if (m_jarFile == null)
202 {
203 m_jarFile = new JarFile(m_file);
204 }
205 }
206
207 public String toString()
208 {
209 return "JAR " + m_file.getPath();
210 }
211}