source: trunk/gcc/libjava/java/net/JarURLConnection.java

Last change on this file was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 8.7 KB
Line 
1/* Copyright (C) 1999, 2000, 2002 Free Software Foundation
2
3 This file is part of libgcj.
4
5This software is copyrighted work licensed under the terms of the
6Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
7details. */
8
9package java.net;
10
11import java.net.*;
12import java.io.*;
13import java.util.jar.*;
14import java.util.zip.*;
15import java.util.Map;
16import java.util.Vector;
17import java.util.Hashtable;
18import java.security.cert.Certificate;
19
20/**
21 * @author Kresten Krab Thorup <krab@gnu.org>
22 * @since 1.2
23 * @date Aug 10, 1999.
24 */
25
26
27public abstract class JarURLConnection extends URLConnection
28{
29 // three different ways to say the same thing
30 private final URL jarFileURL;
31
32 /** The connection to the jar file itself. A JarURLConnection
33 * can represent an entry in a jar file or an entire jar file. In
34 * either case this describes just the jar file itself. */
35 protected URLConnection jarFileURLConnection;
36
37 // If this is a connection to a jar file element this is set, otherwise null.
38 private final String element;
39
40 // Cached JarURLConnection's
41 static Hashtable conn_cache = new Hashtable();
42
43 public URL getJarFileURL ()
44 {
45 return jarFileURL;
46 }
47
48 public String getEntryName ()
49 {
50 return element;
51 }
52
53 /**
54 * Creates a new JarURLConnection
55 *
56 * @exception MalformedURLException If url is invalid
57 *
58 * @specnote This constructor is protected since JDK 1.4
59 */
60 protected JarURLConnection(URL url)
61 throws MalformedURLException
62 {
63 super(url);
64
65 String spec = url.getFile();
66 int bang = spec.indexOf ("!/", 0);
67 if (bang == -1)
68 throw new MalformedURLException (url + ": No `!/' in spec.");
69
70 // Extact the url for the jar itself.
71 jarFileURL = new URL(spec.substring (0, bang));
72
73 // Get the name of the element, if any.
74 element = (bang+2==spec.length() ? null : spec.substring (bang+2));
75 }
76
77 public synchronized void connect() throws IOException
78 {
79 // Call is ignored if already connected.
80 if (connected)
81 return;
82
83 if (getUseCaches())
84 {
85 jarFileURLConnection = (URLConnection) conn_cache.get (jarFileURL);
86
87 if (jarFileURLConnection == null)
88 {
89 jarFileURLConnection = jarFileURL.openConnection ();
90 jarFileURLConnection.setUseCaches (true);
91 jarFileURLConnection.connect ();
92 conn_cache.put (jarFileURL, jarFileURLConnection);
93 }
94 }
95 else
96 {
97 jarFileURLConnection = jarFileURL.openConnection ();
98 jarFileURLConnection.connect ();
99 }
100
101 connected = true;
102 }
103
104 public InputStream getInputStream() throws IOException
105 {
106 if (!connected)
107 connect();
108
109 if (! doInput)
110 throw new ProtocolException("Can't open InputStream if doInput is false");
111
112 if (element == null)
113 {
114 // This is a JarURLConnection for the entire jar file.
115
116 InputStream jar_is = new BufferedInputStream(
117 jarFileURLConnection.getInputStream ());
118 return new JarInputStream(jar_is);
119 }
120
121 // Reaching this point, we're looking for an element of a jar file.
122
123 JarFile jarfile = null;
124
125 try
126 {
127 jarfile = getJarFile ();
128 }
129 catch (java.io.IOException x)
130 {
131 /* ignore */
132 }
133
134 if (jarfile != null)
135 {
136 // this is the easy way...
137 ZipEntry entry = jarfile.getEntry(element);
138 if (entry != null)
139 return jarfile.getInputStream (entry);
140 else
141 return null;
142 }
143 else
144 {
145 // If the jar file is not local, ...
146 JarInputStream zis = new JarInputStream(
147 jarFileURLConnection.getInputStream ());
148
149 // This is hideous, we're doing a linear search...
150 for (ZipEntry ent = zis.getNextEntry ();
151 ent != null;
152 ent = zis.getNextEntry ())
153 {
154 if (element.equals (ent.getName ()))
155 {
156 int size = (int)ent.getSize();
157 byte[] data = new byte[size];
158 zis.read (data, 0, size);
159 return new ByteArrayInputStream (data);
160 }
161 }
162 }
163
164 return null;
165 }
166
167 /**
168 * Return the JAR entry object for this connection, if any
169 *
170 * @exception IOException If an error occurs
171 */
172 public JarEntry getJarEntry () throws IOException
173 {
174 JarFile jarfile = null;
175
176 if (element == null)
177 return null;
178
179 if (! doInput)
180 throw new ProtocolException("Can't open JarEntry if doInput is false");
181
182 try
183 {
184 jarfile = getJarFile ();
185 }
186 catch (IOException x)
187 {
188 /* ignore */
189 }
190
191 if (jarfile == null)
192 {
193 JarInputStream zis = new JarInputStream(
194 jarFileURLConnection.getInputStream ());
195
196 // This is hideous, we're doing a linear search for the thing...
197 for (ZipEntry ent = zis.getNextEntry ();
198 ent != null;
199 ent = zis.getNextEntry ())
200 {
201 if (element.equals (ent.getName ()))
202 {
203 return new JarEntry (ent);
204 }
205 }
206 }
207
208 else
209 {
210 return jarfile.getJarEntry (element);
211 }
212
213 return null;
214 }
215
216 /**
217 * Return the JAR file for this connection
218 *
219 * @exception IOException If an error occurs
220 */
221 public abstract JarFile getJarFile() throws IOException;
222
223
224 // Steal and borrow from protocol/file/Connection.java
225
226 private Hashtable hdrHash = new Hashtable();
227 private Vector hdrVec = new Vector();
228 private boolean gotHeaders = false;
229
230 // Override default method in URLConnection.
231 public String getHeaderField(String name)
232 {
233 try
234 {
235 getHeaders();
236 }
237 catch (IOException x)
238 {
239 return null;
240 }
241 return (String) hdrHash.get(name.toLowerCase());
242 }
243
244 // Override default method in URLConnection.
245 public Map getHeaderFields()
246 {
247 try
248 {
249 getHeaders();
250 }
251 catch (IOException x)
252 {
253 return null;
254 }
255 return hdrHash;
256 }
257
258 // Override default method in URLConnection.
259 public String getHeaderField(int n)
260 {
261 try
262 {
263 getHeaders();
264 }
265 catch (IOException x)
266 {
267 return null;
268 }
269 if (n < hdrVec.size())
270 return getField((String) hdrVec.elementAt(n));
271
272 return null;
273 }
274
275 // Override default method in URLConnection.
276 public String getHeaderFieldKey(int n)
277 {
278 try
279 {
280 getHeaders();
281 }
282 catch (IOException x)
283 {
284 return null;
285 }
286 if (n < hdrVec.size())
287 return getKey((String) hdrVec.elementAt(n));
288
289 return null;
290 }
291
292 private String getKey(String str)
293 {
294 if (str == null)
295 return null;
296 int index = str.indexOf(':');
297 if (index >= 0)
298 return str.substring(0, index);
299 else
300 return null;
301 }
302
303 private String getField(String str)
304 {
305 if (str == null)
306 return null;
307 int index = str.indexOf(':');
308 if (index >= 0)
309 return str.substring(index + 1).trim();
310 else
311 return str;
312 }
313
314 private void getHeaders() throws IOException
315 {
316 if (gotHeaders)
317 return;
318 gotHeaders = true;
319
320 connect();
321
322 // Yes, it is overkill to use the hash table and vector here since
323 // we're only putting one header in the file, but in case we need
324 // to add others later and for consistency, we'll implement it this way.
325
326 // Add the only header we know about right now: Content-length.
327 long len = -1;
328
329 if (element == null)
330 if (jarFileURLConnection != null)
331 len = jarFileURLConnection.getContentLength ();
332 else
333 {
334 JarEntry entry = getJarEntry();
335 if (entry != null)
336 len = entry.getSize ();
337 }
338
339 String line = "Content-length: " + len;
340 hdrVec.addElement(line);
341
342 // The key will never be null in this scenario since we build up the
343 // headers ourselves. If we ever rely on getting a header from somewhere
344 // else, then we may have to check if the result of getKey() is null.
345 String key = getKey(line);
346 hdrHash.put(key.toLowerCase(), Long.toString(len));
347 }
348
349 /**
350 * Returns an array of Certificate objects for the jar file entry specified
351 * by this URL or null if there are none
352 *
353 * @return A Certificate array
354 *
355 * @exception IOException If an error occurs
356 */
357 public Certificate[] getCertificates() throws IOException
358 {
359 return getJarEntry().getCertificates();
360 }
361
362 /**
363 * Returns the main Attributes for the JAR file for this connection
364 *
365 * @exception IOException If an error occurs
366 */
367 public Attributes getMainAttributes () throws IOException
368 {
369 return getManifest ().getMainAttributes ();
370 }
371
372 /**
373 * Return the Attributes object for this connection if the URL for it points
374 * to a JAR file entry, null otherwise
375 *
376 * @exception IOException If an error occurs
377 */
378 public Attributes getAttributes () throws IOException
379 {
380 // FIXME: implement this
381 return null;
382 }
383
384 /**
385 * Returns the Manifest for this connection, or null if none
386 *
387 * @exception IOException If an error occurs
388 */
389 public Manifest getManifest () throws IOException
390 {
391 JarFile file = getJarFile ();
392
393 return (file != null) ? file.getManifest() : null;
394 }
395}
Note: See TracBrowser for help on using the repository browser.