1 package org.jadira.scanner.classpath.projector;
2
3 import java.io.File;
4 import java.io.FileFilter;
5 import java.io.FilenameFilter;
6 import java.io.IOException;
7 import java.util.ArrayList;
8 import java.util.Arrays;
9 import java.util.Enumeration;
10 import java.util.HashMap;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.jar.JarEntry;
14 import java.util.jar.JarFile;
15
16 import org.jadira.scanner.core.api.Projector;
17 import org.jadira.scanner.core.exception.ClasspathAccessException;
18
19 import de.schlichtherle.io.archive.zip.ZipEntry;
20 import de.schlichtherle.util.zip.ZipFile;
21
22 public class ClasspathProjector implements Projector<File> {
23
24 public static final ClasspathProjector SINGLETON = new ClasspathProjector();
25
26 private static final Map<File, List<File>> PROJECTION_CACHE = new HashMap<File, List<File>>();
27
28 public ClasspathProjector() {
29 // TODO Preload the projection cache if possible
30 }
31
32 @Override
33 public List<File> project(File segment) {
34
35 List<File> files = PROJECTION_CACHE.get(segment);
36 if (files != null) {
37 return files;
38 }
39
40 files = new ArrayList<File>();
41 boolean isArchive = false;
42
43 if (segment instanceof de.schlichtherle.io.File) {
44 if (((de.schlichtherle.io.File)segment).isArchive()) {
45 isArchive = true;
46 }
47 }
48
49 // if (segment.toString().startsWith(System.getProperty("java.home"))) {
50 // String cacheFileKey = buildFileKey(segment);
51 // ClassLoader[] classLoaders = ClassLoaderUtils.getClassLoaders();
52 //
53 // for (ClassLoader cl : classLoaders) {
54 //
55 // InputStream is = null;
56 // InputStreamReader isr = null;
57 // BufferedReader br = null;
58 // try {
59 // is = cl.getResourceAsStream(cacheFileKey);
60 // if (is != null) {
61 // isr = new InputStreamReader(is);
62 // br = new BufferedReader(isr, 16384);
63 // String nextLine;
64 // try {
65 // while ((nextLine = br.readLine()) != null) {
66 // files.add(new de.schlichtherle.io.File(segment.getPath() + System.getProperty("file.separator") + nextLine));
67 // }
68 // } catch (IOException e) {
69 // throw new ClasspathAccessException("Could not open Cached File List: " + e.getMessage(), e);
70 // }
71 // PROJECTION_CACHE.put(segment, files);
72 // return files;
73 // }
74 // } finally {
75 // if (is != null) {
76 // try {
77 // is.close();
78 // } catch (IOException e) {
79 // }
80 // }
81 // if (isr != null) {
82 // try {
83 // isr.close();
84 // } catch (IOException e) {
85 // }
86 // }
87 // if (br != null) {
88 // try {
89 // br.close();
90 // } catch (IOException e) {
91 // }
92 // }
93 // }
94 // }
95 // projectCachedJavaHome(segment);
96 // }
97
98 if (!isArchive) {
99
100 File[] dirs = segment.listFiles(new FileFilter() {
101
102 @Override
103 public boolean accept(File file) {
104 return file.isDirectory();
105 }
106 });
107
108 for (File dir : dirs) {
109 files.addAll(project(dir));
110 }
111
112 File[] classes = segment.listFiles(new FileFilter() {
113
114 @Override
115 public boolean accept(File file) {
116 return !file.isDirectory() && file.getName().endsWith(".class");
117 }
118 });
119 files.addAll(Arrays.asList(classes));
120
121 } else if (segment.getPath().endsWith("jar")) { // else if ("jar".equals(((de.schlichtherle.io.File)segment).getArchiveDetector().getScheme(segment.getPath()).toString())) {
122
123 JarFile jarFile = null;
124 try {
125 jarFile = new JarFile(segment.getPath());
126 Enumeration<JarEntry> entries = jarFile.entries();
127 while (entries.hasMoreElements()) {
128 JarEntry next = entries.nextElement();
129 if (next.getName().endsWith(".class")) {
130 files.add(new de.schlichtherle.io.File(segment.getPath() + System.getProperty("file.separator") + next.getName()));
131 }
132 }
133 } catch (IOException e) {
134 throw new ClasspathAccessException("Could not open JarFile: " + e.getMessage(), e);
135 } finally {
136 if (jarFile != null) {
137 try {
138 jarFile.close();
139 } catch (IOException e) {
140 // Ignore this
141 }
142 }
143 }
144 } else if (segment.getPath().endsWith("zip")) { // else if ("zip".equals(((TFile)segment).getArchiveDetector().getScheme(segment.getPath()).toString())) {
145 ZipFile zipFile = null;
146 try {
147 zipFile = new ZipFile(segment.getPath());
148 @SuppressWarnings("unchecked")
149 Enumeration<ZipEntry> entries = zipFile.entries();
150 while (entries.hasMoreElements()) {
151 ZipEntry next = entries.nextElement();
152 if (next.getName().endsWith(".class")) {
153 files.add(new de.schlichtherle.io.File(segment.getPath() + System.getProperty("file.separator") + next.getName()));
154 }
155 }
156 } catch (IOException e) {
157 throw new ClasspathAccessException("Could not open ZipFile: " + e.getMessage(), e);
158 } finally {
159 if (zipFile != null) {
160 try {
161 zipFile.close();
162 } catch (IOException e) {
163 // Ignore this
164 }
165 }
166 }
167 } else {
168
169 File[] classes = ((de.schlichtherle.io.File)segment).listFiles(new FilenameFilter() {
170
171 @Override
172 public boolean accept(File dir, String name) {
173 return name.endsWith(".class");
174 }
175 });
176 files.addAll(Arrays.asList(classes));
177 }
178 PROJECTION_CACHE.put(segment, files);
179 return files;
180 }
181
182 // private String buildFileKey(File segment) {
183 // return ((("java-"
184 // + System.getProperty("java.vendor")
185 // + "-"
186 // + System.getProperty("java.version")
187 // + (segment.toString().substring(System.getProperty("java.home").length())))
188 // .replace('/', '_')
189 // .replace('\\', '_')
190 // .replace(' ', '_')
191 // .replace('.', '_')) + ".classes");
192 // }
193 //
194 // private void projectCachedJavaHome(File segment) {
195 //
196 // StringBuilder sb = new StringBuilder(buildFileKey(segment));
197 // sb.append(System.getProperty("line.separator"));
198 // sb.append(System.getProperty("line.separator"));
199 // JarFile jarFile = null;
200 // try {
201 // jarFile = new JarFile(segment.getPath());
202 // Enumeration<JarEntry> entries = jarFile.entries();
203 // while (entries.hasMoreElements()) {
204 // JarEntry next = entries.nextElement();
205 // if (next.getName().endsWith(".class")) {
206 // sb.append(next.getName());
207 // sb.append(System.getProperty("line.separator"));
208 // }
209 // }
210 // } catch (IOException e) {
211 // throw new ClasspathAccessException("Could not open JarFile: " + e.getMessage(), e);
212 // } finally {
213 // if (jarFile != null) {
214 // try {
215 // jarFile.close();
216 // } catch (IOException e) {
217 // // Ignore this
218 // }
219 // }
220 // }
221 // sb.append(System.getProperty("line.separator"));
222 // sb.append(System.getProperty("line.separator"));
223 // System.err.println(sb);
224 // }
225 }