OSDN Git Service

Sun Aug 20 09:51:48 2000 Anthony Green <green@redhat.com>
[pf3gnuchains/gcc-fork.git] / libjava / java / net / URLClassLoader.java
1 /* Copyright (C) 1999, 2000  Free Software Foundation
2
3    This file is part of libgcj.
4
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
7 details.  */
8
9 package java.net;
10
11 import java.io.*;
12 import java.util.jar.*;
13 import java.util.Vector;
14
15 public class URLClassLoader extends ClassLoader 
16 {
17   // The URLStreamHandlerFactory
18   URLStreamHandlerFactory factory = null;
19
20   // `path' contains simply the URL's we're using for the searching.
21   private Vector path; 
22
23   // If path[n] is a zip/jar, then this holds a JarURLConnection for
24   // that thing, otherwise, path[n] is null.
25   private Vector info; 
26
27   private URLStreamHandler getHandler0 (String protocol)
28   {
29     if (factory != null)
30       return factory.createURLStreamHandler(protocol);
31     else
32       return null;
33   }
34
35   public URLClassLoader (URL[] urls)
36   { 
37     this (urls, null, null);
38   }
39   
40   public URLClassLoader (URL[] urls, ClassLoader parent)
41   { 
42     this (urls, parent, null);
43   }
44
45   public URLClassLoader (URL[] urls, ClassLoader parent,
46                          URLStreamHandlerFactory fac)
47   { 
48     super (parent);
49
50     factory = fac;
51
52     if (urls == null || urls.length == 0)
53       {
54         path = new Vector (1);
55         info = new Vector (1);
56         return;
57       }
58
59     path = new Vector (urls.length);
60     info = new Vector (urls.length);
61
62     for (int i = 0; i < urls.length; i++)
63       {
64         URL u = urls[i];
65
66         // If it is a jar url, then we'll search it as is.  
67         if (! u.getProtocol ().equals ("jar"))
68           {
69             String f = u.getFile ();
70
71             // If it ends with '/' we'll take it for a directory,
72             // otherwise it's a jar file.  This is how JDK 1.2 defines
73             // it, so we will not try to be smart here.
74             if (f.charAt (f.length ()-1) != '/')
75               {
76                 try
77                   {
78                     u = new URL ("jar", "", -1, (u.toExternalForm ())+"!/", 
79                                  getHandler0 ("jar"));
80                   } 
81                 catch (MalformedURLException x)
82                   {
83                     /* ignore */
84                   }
85               }
86           }
87
88         path.insertElementAt (u, i);
89
90         if (u.getProtocol ().equals ("jar"))
91           {
92             JarURLConnection conn = null;
93             try
94               {
95                 conn = (JarURLConnection) u.openConnection ();
96               }
97             catch (java.io.IOException x)
98               {
99                 /* ignore */
100               }
101             info.insertElementAt (conn, i);
102           }
103         else
104           {
105             info.insertElementAt (null, i);
106           }
107       }
108   }
109   
110   public URL getResource (String name)
111   {
112     for (int i = 0; i < path.size(); i++)
113       {
114         URL u    = (URL)path.elementAt (i);
115         
116         try {
117           JarURLConnection conn = (JarURLConnection) info.elementAt (i);
118           
119           if (conn != null)
120             {
121               if (conn.getJarFile().getJarEntry (name) != null)
122                 return new URL(u, name, getHandler0 (u.getProtocol()));
123             }
124           else
125             {
126               URL p = new URL (u, name, getHandler0 (u.getProtocol()));
127
128               InputStream is = p.openStream();
129               if (is != null)
130                 {
131                   is.close();
132                   return p;
133                 }
134             }
135         
136           // if we get an exception ... try the next path element
137         } catch (IOException x) {
138           continue;
139         }
140       }
141
142     return null;
143   }
144
145   /** IN jdk 1.2 this method is not overridden, but we gain performance
146       by doing so.
147    */
148
149   public InputStream getResourceAsStream (String name)
150   {
151     for (int i = 0; i < path.size(); i++)
152       {
153         URL u    = (URL)path.elementAt (i);
154         
155         try {
156           JarURLConnection conn = (JarURLConnection) info.elementAt (i);
157           
158           if (conn != null)
159             {
160               JarFile file = conn.getJarFile ();
161               JarEntry ent = file.getJarEntry (name);
162               if (ent != null)
163                 return file.getInputStream(ent);
164             }
165           else
166             {
167               InputStream is = new URL(u, name, getHandler0 (u.getProtocol())).openStream();
168               if (is != null)
169                 return is;
170             }
171         
172           // if we get an exception ... try the next path element
173         } catch (IOException x) {
174           continue;
175         }
176       }
177
178     return null;
179   }
180
181   // and finally, we can implement our class loader functionality.
182   protected Class findClass (String name)
183     throws ClassNotFoundException
184   {
185     if (name == null)
186       throw new ClassNotFoundException ("null");
187
188     try 
189       {
190         URL u = getResource (name.replace ('.', '/') + ".class");
191
192         if (u == null)
193           throw new ClassNotFoundException (name);
194
195         URLConnection connection = u.openConnection ();
196         InputStream is = connection.getInputStream ();
197
198         int len = connection.getContentLength ();
199         byte[] data = new byte[len];
200
201         int left = len;
202         int off  = 0;
203         while (left > 0)
204           {
205             int c = is.read (data, off, len-off);
206             if (c == -1 || c == 0)
207               throw new InternalError ("premature end of file");
208             left -= c;
209             off += c;
210           }
211
212         return defineClass (name, data, 0, len);
213       } 
214     catch (java.io.IOException x)
215       {
216         throw new ClassNotFoundException(name);
217       }
218   }
219 }
220