KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tonicsystems > jarjar > util > ClassPathIterator


1 /*
2   Jar Jar Links - A utility to repackage and embed Java libraries
3   Copyright (C) 2004 Tonic Systems, Inc.
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program; see the file COPYING. if not, write to
17   the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18   Boston, MA 02111-1307 USA
19 */

20
21 package com.tonicsystems.jarjar.util;
22
23 import java.util.*;
24 import java.util.zip.*;
25 import java.io.*;
26 import java.util.jar.*;
27
28 public class ClassPathIterator implements Iterator
29 {
30     private static final FileFilter CLASS_FILTER = new FileFilter() {
31         public boolean accept(File file) {
32             return file.isDirectory() || hasExtension(getName(file), ".class");
33         }
34     };
35
36     private static final FileFilter JAR_FILTER = new FileFilter() {
37         public boolean accept(File file) {
38             return hasExtension(getName(file), ".jar");
39         }
40     };
41     
42     private Iterator files;
43     private File parent;
44     private Enumeration entries;
45     private Map sources = new HashMap();
46     private ZipFile zip;
47     private Object JavaDoc next;
48
49     public ClassPathIterator(String JavaDoc classPath) {
50         this(new File(System.getProperty("user.dir")), classPath);
51     }
52     
53     public ClassPathIterator(File parent, String JavaDoc classPath) {
54         StringTokenizer st = new StringTokenizer(classPath, System.getProperty("path.separator"));
55         List fileList = new ArrayList();
56         while (st.hasMoreTokens()) {
57             String JavaDoc part = (String JavaDoc)st.nextElement();
58
59             boolean wildcard = false;
60             if (part.endsWith("/*")) {
61                 part = part.substring(0, part.length() - 1);
62                 if (part.indexOf('*') >= 0)
63                     throw new IllegalArgumentException JavaDoc("Multiple wildcards are not allowed: " + part);
64                 wildcard = true;
65             } else if (part.indexOf('*') >= 0) {
66                 throw new IllegalArgumentException JavaDoc("Incorrect wildcard usage: " + part);
67             }
68                 
69             File file = new File(part);
70             if (!file.isAbsolute())
71                 file = new File(parent, part);
72             if (!file.exists())
73                 throw new IllegalArgumentException JavaDoc("File " + file + " does not exist");
74
75             if (wildcard) {
76                 if (!file.isDirectory())
77                     throw new IllegalArgumentException JavaDoc("File " + file + " + is not a directory");
78                 fileList.addAll(findFiles(file, JAR_FILTER, false, new ArrayList()));
79             } else {
80                 fileList.add(file);
81             }
82         }
83         this.files = fileList.iterator();
84         advance();
85     }
86
87     public boolean hasNext() {
88         return next != null;
89     }
90
91     public void close() throws IOException {
92         if (sources != null) {
93             for (Iterator it = sources.values().iterator(); it.hasNext();) {
94                 Object JavaDoc obj = it.next();
95                 if (obj instanceof ZipFile)
96                     ((ZipFile)obj).close();
97             }
98         }
99     }
100     
101     public InputStream getInputStream(Object JavaDoc obj) throws IOException {
102         if (obj instanceof ZipEntry) {
103             return ((ZipFile)sources.get(obj)).getInputStream((ZipEntry)obj);
104         } else {
105             return new BufferedInputStream(new FileInputStream((File)obj));
106         }
107     }
108
109     public Object JavaDoc getSource(Object JavaDoc obj) {
110         return sources.get(obj);
111     }
112
113     public void remove() {
114         throw new UnsupportedOperationException JavaDoc();
115     }
116
117     public Object JavaDoc next() {
118         if (!hasNext())
119             throw new NoSuchElementException();
120         Object JavaDoc result = next;
121         advance();
122         return result;
123     }
124
125     private void advance() {
126         try {
127             
128             if (entries == null) {
129                 if (!files.hasNext()) {
130                     next = null;
131                     return;
132                 }
133                 zip = null;
134                 File file = (File)files.next();
135                 if (hasExtension(getName(file), ".jar")) {
136                     zip = new JarFile(file);
137                     entries = zip.entries();
138                 } else if (hasExtension(getName(file), ".zip")) {
139                     zip = new ZipFile(file);
140                     entries = zip.entries();
141                 } else if (file.isDirectory()) {
142                     // TODO: could lazily recurse for performance
143
List classes = findFiles(file, CLASS_FILTER, true, new ArrayList());
144                     for (Iterator it = classes.iterator(); it.hasNext();) {
145                         sources.put(it.next(), file);
146                     }
147                     entries = Collections.enumeration(classes);
148                 } else {
149                     throw new IllegalArgumentException JavaDoc("Do not know how to handle " + file);
150                 }
151             }
152
153             boolean foundClass = false;
154             while (entries.hasMoreElements()) {
155                 next = entries.nextElement();
156                 if (foundClass = hasExtension(getName(next), ".class")) {
157                     if (zip != null)
158                         sources.put(next, zip);
159                     break;
160                 }
161             }
162             if (!foundClass) {
163                 entries = null;
164                 advance();
165             }
166         } catch (IOException e) {
167             throw new RuntimeIOException(e);
168         }
169     }
170
171     private static List findFiles(File dir, FileFilter filter, boolean recurse, List collect) {
172         File[] files = dir.listFiles(filter);
173         for (int i = 0; i < files.length; i++) {
174             if (recurse && files[i].isDirectory()) {
175                 findFiles(files[i], filter, recurse, collect);
176             } else {
177                 collect.add(files[i]);
178             }
179         }
180         return collect;
181     }
182
183     private static String JavaDoc getName(Object JavaDoc obj) {
184         return (obj instanceof ZipEntry) ? ((ZipEntry)obj).getName() : ((File)obj).getName();
185     }
186
187     private static boolean hasExtension(String JavaDoc name, String JavaDoc ext) {
188         int len = name.length();
189         if (name.length() < ext.length())
190             return false;
191         String JavaDoc actual = name.substring(name.length() - ext.length());
192         return actual.equals(ext) || actual.equals(ext.toUpperCase());
193     }
194 }
195
Popular Tags