1: package ;
2:
3: import ;
4:
5: import ;
6: import ;
7: import ;
8: import ;
9: import ;
10: import ;
11: import ;
12: import ;
13: import ;
14: import ;
15: import ;
16: import ;
17: import ;
18: import ;
19: import ;
20: import ;
21:
22:
26: public final class JarURLLoader extends URLLoader
27: {
28:
29: boolean initialized;
30:
31: JarFile jarfile;
32:
33: final URL baseJarURL;
34:
35: ArrayList<URLLoader> classPath;
36:
37:
38:
39: Set indexSet;
40:
41:
42:
43:
44: private JarURLLoader(URLClassLoader classloader, URLStreamHandlerCache cache,
45: URLStreamHandlerFactory factory,
46: URL baseURL, URL absoluteUrl,
47: Set indexSet)
48: {
49: super(classloader, cache, factory, baseURL, absoluteUrl);
50:
51: URL newBaseURL = null;
52: try
53: {
54:
55: String base = baseURL.toExternalForm() + "!/";
56: newBaseURL = new URL("jar", "", -1, base, cache.get(factory, "jar"));
57: }
58: catch (MalformedURLException ignore)
59: {
60:
61: }
62: this.baseJarURL = newBaseURL;
63: this.classPath = null;
64: this.indexSet = indexSet;
65: }
66:
67:
68:
69:
70:
71: public JarURLLoader(URLClassLoader classloader, URLStreamHandlerCache cache,
72: URLStreamHandlerFactory factory,
73: URL baseURL, URL absoluteUrl)
74: {
75: this(classloader, cache, factory, baseURL, absoluteUrl, null);
76: initialize();
77: }
78:
79: private void initialize()
80: {
81: JarFile jarfile = null;
82: try
83: {
84: jarfile =
85: ((JarURLConnection) baseJarURL.openConnection()).getJarFile();
86:
87: Manifest manifest;
88: Attributes attributes;
89: String classPathString;
90:
91: IndexListParser parser = new IndexListParser(jarfile, baseJarURL,
92: baseURL);
93: LinkedHashMap<URL, Set<String>> indexMap = parser.getHeaders();
94: if (indexMap != null)
95: {
96:
97:
98:
99:
100: this.classPath = new ArrayList<URLLoader>();
101: Iterator<Map.Entry<URL, Set<String>>> it = indexMap.entrySet().iterator();
102: while (it.hasNext())
103: {
104: Map.Entry<URL, Set<String>> entry = it.next();
105: URL subURL = entry.getKey();
106: Set<String> prefixes = entry.getValue();
107: if (subURL.equals(baseURL))
108: this.indexSet = prefixes;
109: else
110: {
111: JarURLLoader subLoader = new JarURLLoader(classloader,
112: cache,
113: factory, subURL,
114: subURL,
115: prefixes);
116:
117:
118:
119:
120: this.classPath.add(subLoader);
121: }
122: }
123: }
124: else if ((manifest = jarfile.getManifest()) != null
125: && (attributes = manifest.getMainAttributes()) != null
126: && ((classPathString
127: = attributes.getValue(Attributes.Name.CLASS_PATH))
128: != null))
129: {
130: this.classPath = new ArrayList<URLLoader>();
131: StringTokenizer st = new StringTokenizer(classPathString, " ");
132: while (st.hasMoreElements ())
133: {
134: String e = st.nextToken ();
135: try
136: {
137: URL subURL = new URL(baseURL, e);
138:
139:
140:
141: if (subURL.equals(baseURL))
142: continue;
143: JarURLLoader subLoader = new JarURLLoader(classloader,
144: cache, factory,
145: subURL, subURL);
146: this.classPath.add(subLoader);
147: ArrayList<URLLoader> extra = subLoader.getClassPath();
148: if (extra != null)
149: this.classPath.addAll(extra);
150: }
151: catch (java.net.MalformedURLException xx)
152: {
153:
154: }
155: }
156: }
157: }
158: catch (IOException ioe)
159: {
160:
161: }
162:
163: this.jarfile = jarfile;
164: this.initialized = true;
165: }
166:
167:
168: public Resource getResource(String name)
169: {
170: if (name.startsWith("/"))
171: name = name.substring(1);
172: if (indexSet != null)
173: {
174:
175: String basename = name;
176: int offset = basename.lastIndexOf('/');
177: if (offset != -1)
178: basename = basename.substring(0, offset);
179: if (! indexSet.contains(basename))
180: return null;
181:
182:
183:
184:
185: }
186:
187: if (! initialized)
188: initialize();
189: if (jarfile == null)
190: return null;
191:
192: JarEntry je = jarfile.getJarEntry(name);
193: if (je != null)
194: return new JarURLResource(this, name, je);
195: else
196: return null;
197: }
198:
199: public Manifest getManifest()
200: {
201: try
202: {
203: return (jarfile == null) ? null : jarfile.getManifest();
204: }
205: catch (IOException ioe)
206: {
207: return null;
208: }
209: }
210:
211: public ArrayList<URLLoader> getClassPath()
212: {
213: return classPath;
214: }
215: }