View Javadoc
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 }