History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/misc/JarIndex.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/misc/JarIndex.java+360−0
@@ -0,0 +1,360 @@
1/*
2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package sun.misc;
27
28import java.io.*;
29import java.util.*;
30import java.util.jar.*;
31import java.util.zip.*;
32
33/**
34 * This class is used to maintain mappings from packages, classes
35 * and resources to their enclosing JAR files. Mappings are kept
36 * at the package level except for class or resource files that
37 * are located at the root directory. URLClassLoader uses the mapping
38 * information to determine where to fetch an extension class or
39 * resource from.
40 *
41 * @author Zhenghua Li
42 * @since 1.3
43 */
44
45public class JarIndex {
46
47 /**
48 * The hash map that maintains mappings from
49 * package/classe/resource to jar file list(s)
50 */
51 private HashMap indexMap;
52
53 /**
54 * The hash map that maintains mappings from
55 * jar file to package/class/resource lists
56 */
57 private HashMap jarMap;
58
59 /*
60 * An ordered list of jar file names.
61 */
62 private String[] jarFiles;
63
64 /**
65 * The index file name.
66 */
67 public static final String INDEX_NAME = "META-INF/INDEX.LIST";
68
69 /**
70 * true if, and only if, sun.misc.JarIndex.metaInfFilenames is set to true.
71 * If true, the names of the files in META-INF, and its subdirectories, will
72 * be added to the index. Otherwise, just the directory names are added.
73 */
74 private static final boolean metaInfFilenames =
75 "true".equals(System.getProperty("sun.misc.JarIndex.metaInfFilenames"));
76
77 /**
78 * Constructs a new, empty jar index.
79 */
80 public JarIndex() {
81 indexMap = new HashMap();
82 jarMap = new HashMap();
83 }
84
85 /**
86 * Constructs a new index from the specified input stream.
87 *
88 * @param is the input stream containing the index data
89 */
90 public JarIndex(InputStream is) throws IOException {
91 this();
92 read(is);
93 }
94
95 /**
96 * Constructs a new index for the specified list of jar files.
97 *
98 * @param files the list of jar files to construct the index from.
99 */
100 public JarIndex(String[] files) throws IOException {
101 this();
102 this.jarFiles = files;
103 parseJars(files);
104 }
105
106 /**
107 * Returns the jar index, or <code>null</code> if none.
108 *
109 * This single parameter version of the method is retained
110 * for binary compatibility with earlier releases.
111 *
112 * @param jar the JAR file to get the index from.
113 * @exception IOException if an I/O error has occurred.
114 */
115 public static JarIndex getJarIndex(JarFile jar) throws IOException {
116 return getJarIndex(jar, null);
117 }
118
119 /**
120 * Returns the jar index, or <code>null</code> if none.
121 *
122 * @param jar the JAR file to get the index from.
123 * @exception IOException if an I/O error has occurred.
124 */
125 public static JarIndex getJarIndex(JarFile jar, MetaIndex metaIndex) throws IOException {
126 JarIndex index = null;
127 /* If metaIndex is not null, check the meta index to see
128 if META-INF/INDEX.LIST is contained in jar file or not.
129 */
130 if (metaIndex != null &&
131 !metaIndex.mayContain(INDEX_NAME)) {
132 return null;
133 }
134 JarEntry e = jar.getJarEntry(INDEX_NAME);
135 // if found, then load the index
136 if (e != null) {
137 index = new JarIndex(jar.getInputStream(e));
138 }
139 return index;
140 }
141
142 /**
143 * Returns the jar files that are defined in this index.
144 */
145 public String[] getJarFiles() {
146 return jarFiles;
147 }
148
149 /*
150 * Add the key, value pair to the hashmap, the value will
151 * be put in a linked list which is created if necessary.
152 */
153 private void addToList(String key, String value, HashMap t) {
154 LinkedList list = (LinkedList)t.get(key);
155 if (list == null) {
156 list = new LinkedList();
157 list.add(value);
158 t.put(key, list);
159 } else if (!list.contains(value)) {
160 list.add(value);
161 }
162 }
163
164 /**
165 * Returns the list of jar files that are mapped to the file.
166 *
167 * @param fileName the key of the mapping
168 */
169 public LinkedList get(String fileName) {
170 LinkedList jarFiles = null;
171 if ((jarFiles = (LinkedList)indexMap.get(fileName)) == null) {
172 /* try the package name again */
173 int pos;
174 if((pos = fileName.lastIndexOf("/")) != -1) {
175 jarFiles = (LinkedList)indexMap.get(fileName.substring(0, pos));
176 }
177 }
178 return jarFiles;
179 }
180
181 /**
182 * Add the mapping from the specified file to the specified
183 * jar file. If there were no mapping for the package of the
184 * specified file before, a new linked list will be created,
185 * the jar file is added to the list and a new mapping from
186 * the package to the jar file list is added to the hashmap.
187 * Otherwise, the jar file will be added to the end of the
188 * existing list.
189 *
190 * @param fileName the file name
191 * @param jarName the jar file that the file is mapped to
192 *
193 */
194 public void add(String fileName, String jarName) {
195 String packageName;
196 int pos;
197 if((pos = fileName.lastIndexOf("/")) != -1) {
198 packageName = fileName.substring(0, pos);
199 } else {
200 packageName = fileName;
201 }
202
203 // add the mapping to indexMap
204 addToList(packageName, jarName, indexMap);
205
206 // add the mapping to jarMap
207 addToList(jarName, packageName, jarMap);
208 }
209
210 /**
211 * Same as add(String,String) except that it doesn't strip off from the
212 * last index of '/'. It just adds the filename.
213 */
214 private void addExplicit(String fileName, String jarName) {
215 // add the mapping to indexMap
216 addToList(fileName, jarName, indexMap);
217
218 // add the mapping to jarMap
219 addToList(jarName, fileName, jarMap);
220 }
221
222 /**
223 * Go through all the jar files and construct the
224 * index table.
225 */
226 private void parseJars(String[] files) throws IOException {
227 if (files == null) {
228 return;
229 }
230
231 String currentJar = null;
232
233 for (int i = 0; i < files.length; i++) {
234 currentJar = files[i];
235 ZipFile zrf = new ZipFile(currentJar.replace
236 ('/', File.separatorChar));
237
238 Enumeration entries = zrf.entries();
239 while(entries.hasMoreElements()) {
240 ZipEntry entry = (ZipEntry) entries.nextElement();
241 String fileName = entry.getName();
242
243 // Skip the META-INF directory, the index, and manifest.
244 // Any files in META-INF/ will be indexed explicitly
245 if (fileName.equals("META-INF/") ||
246 fileName.equals(INDEX_NAME) ||
247 fileName.equals(JarFile.MANIFEST_NAME))
248 continue;
249
250 if (!metaInfFilenames) {
251 add(fileName, currentJar);
252 } else {
253 if (!fileName.startsWith("META-INF/")) {
254 add(fileName, currentJar);
255 } else if (!entry.isDirectory()) {
256 // Add files under META-INF explicitly so that certain
257 // services, like ServiceLoader, etc, can be located
258 // with greater accuracy. Directories can be skipped
259 // since each file will be added explicitly.
260 addExplicit(fileName, currentJar);
261 }
262 }
263 }
264
265 zrf.close();
266 }
267 }
268
269 /**
270 * Writes the index to the specified OutputStream
271 *
272 * @param out the output stream
273 * @exception IOException if an I/O error has occurred
274 */
275 public void write(OutputStream out) throws IOException {
276 BufferedWriter bw = new BufferedWriter
277 (new OutputStreamWriter(out, "UTF8"));
278 bw.write("JarIndex-Version: 1.0\n\n");
279
280 if (jarFiles != null) {
281 for (int i = 0; i < jarFiles.length; i++) {
282 /* print out the jar file name */
283 String jar = jarFiles[i];
284 bw.write(jar + "\n");
285 LinkedList jarlist = (LinkedList)jarMap.get(jar);
286 if (jarlist != null) {
287 Iterator listitr = jarlist.iterator();
288 while(listitr.hasNext()) {
289 bw.write((String)(listitr.next()) + "\n");
290 }
291 }
292 bw.write("\n");
293 }
294 bw.flush();
295 }
296 }
297
298
299 /**
300 * Reads the index from the specified InputStream.
301 *
302 * @param is the input stream
303 * @exception IOException if an I/O error has occurred
304 */
305 public void read(InputStream is) throws IOException {
306 BufferedReader br = new BufferedReader
307 (new InputStreamReader(is, "UTF8"));
308 String line = null;
309 String currentJar = null;
310
311 /* an ordered list of jar file names */
312 Vector jars = new Vector();
313
314 /* read until we see a .jar line */
315 while((line = br.readLine()) != null && !line.endsWith(".jar"));
316
317 for(;line != null; line = br.readLine()) {
318 if (line.length() == 0)
319 continue;
320
321 if (line.endsWith(".jar")) {
322 currentJar = line;
323 jars.add(currentJar);
324 } else {
325 String name = line;
326 addToList(name, currentJar, indexMap);
327 addToList(currentJar, name, jarMap);
328 }
329 }
330
331 jarFiles = (String[])jars.toArray(new String[jars.size()]);
332 }
333
334 /**
335 * Merges the current index into another index, taking into account
336 * the relative path of the current index.
337 *
338 * @param toIndex The destination index which the current index will
339 * merge into.
340 * @param path The relative path of the this index to the destination
341 * index.
342 *
343 */
344 public void merge(JarIndex toIndex, String path) {
345 Iterator itr = indexMap.entrySet().iterator();
346 while(itr.hasNext()) {
347 Map.Entry e = (Map.Entry)itr.next();
348 String packageName = (String)e.getKey();
349 LinkedList from_list = (LinkedList)e.getValue();
350 Iterator listItr = from_list.iterator();
351 while(listItr.hasNext()) {
352 String jarName = (String)listItr.next();
353 if (path != null) {
354 jarName = path.concat(jarName);
355 }
356 toIndex.add(packageName, jarName);
357 }
358 }
359 }
360}