1 /**
2  *  ServingXML
3  *
4  *  Copyright (C) 2006  Daniel Parker
5  *    daniel.parker@servingxml.com
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  **/
20 
21 package com.servingxml.util;
22 
23 import java.net.URL;
24 import java.net.MalformedURLException;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.net.URLClassLoader;
28 import java.util.StringTokenizer;
29 import java.util.jar.Attributes;
30 import java.util.jar.JarFile;
31 import java.util.jar.JarInputStream;
32 import java.util.jar.Manifest;
33 import java.util.Set;
34 import java.util.HashSet;
35 import java.util.Iterator;
36 
37 /**
38  *
39  *
40  * @author Daniel A. Parker (daniel.parker@servingxml.com)
41  */
42 
43 public class JarFileIterator {
44 
45   public static interface Command {
doEntry(URL url)46     public void doEntry(URL url);
47   }
48 
toEveryJarFile(String entryKey, Command command)49   public static void toEveryJarFile(String entryKey, Command command) {
50 
51     Set<URL> jarUrlSet = new HashSet<URL>();
52 
53     ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
54 
55     while (classLoader != null) {
56       if (classLoader instanceof URLClassLoader) {
57         URL[] urls = ((URLClassLoader) classLoader).getURLs();
58         if (urls != null) {
59           for (int i=0; i < urls.length; ++i) {
60             // If it's a jar, get Class-Path entries from manifest
61             URL base = urls[i];
62             InputStream is = null;
63             try {
64               is = base.openStream();
65               JarInputStream jis;
66               try {
67                   jis = new JarInputStream(is,true);
68               } catch (java.io.IOException ioe) {
69                   jis = null;
70               }
71               if (jis != null) {
72                 Manifest manifest = jis.getManifest();
73                 if (manifest != null) {
74                   Attributes attributes = manifest.getMainAttributes();
75                   if (attributes != null) {
76                     addToUrlSet(base,attributes,entryKey,jarUrlSet);
77 
78                     String classPath = attributes.getValue(java.util.jar.Attributes.Name.CLASS_PATH);
79 
80                     //System.out.println("class path = " + classPath);
81                     if (classPath != null) {
82                       StringTokenizer st = new StringTokenizer(classPath, " ");
83                       while (st.hasMoreTokens()) {
84                         String classPathEntry = st.nextToken();
85                         URL jarurl = new URL(base,classPathEntry);
86                         //System.out.println("base = " + base + ", classPathEntry = " + classPathEntry + ", jarurl = " + jarurl.toString());
87 
88                         InputStream is2 = null;
89                         try {
90                           is2 = jarurl.openStream();
91                           JarInputStream jis2 = new JarInputStream(is2,true);
92                           Manifest manifest2 = jis2.getManifest();
93                           if (manifest2 != null) {
94                             Attributes attributes2 = manifest2.getMainAttributes();
95                             if (attributes2 != null) {
96                               addToUrlSet(jarurl,attributes2,entryKey,jarUrlSet);
97                             }
98                           }
99                         } catch (Exception e) {
100                         } finally {
101                           try {
102                             if (is2 != null) {
103                               is2.close();
104                             }
105                           } catch (IOException e) {
106                           }
107                         }
108                       }
109                     }
110                   }
111 
112                 }
113               }
114             } catch (Exception e) {
115             } finally {
116               try {
117                 if (is != null) {
118                   is.close();
119                 }
120               } catch (IOException e) {
121               }
122             }
123 
124           }
125         }
126       }
127       classLoader = classLoader.getParent();
128     }
129 
130     Iterator<URL> iter = jarUrlSet.iterator();
131     while (iter.hasNext()) {
132       URL url = iter.next();
133       command.doEntry(url);
134     }
135   }
136 
addToUrlSet(URL base, Attributes attributes, String entryKey, Set<URL> urlSet)137   static void addToUrlSet(URL base, Attributes attributes, String entryKey, Set<URL> urlSet)
138   throws MalformedURLException {
139     String entry = attributes.getValue(entryKey);
140     if (entry != null) {
141       if (!entry.startsWith("/")) {
142         entry = "/" + entry;
143       }
144       String systemId = "jar:" + base.toString() + "!" + entry;
145 
146       //System.out.println("jar entry system id2 = " + systemId);
147 
148       URL url = new URL(systemId);
149       urlSet.add(url);
150     }
151   }
152 }
153 
154