001package org.jadira.scanner.classpath.projector; 002 003import java.io.File; 004import java.io.FileFilter; 005import java.io.FilenameFilter; 006import java.io.IOException; 007import java.util.ArrayList; 008import java.util.Arrays; 009import java.util.Enumeration; 010import java.util.HashMap; 011import java.util.List; 012import java.util.Map; 013import java.util.jar.JarEntry; 014import java.util.jar.JarFile; 015 016import org.jadira.scanner.core.api.Projector; 017import org.jadira.scanner.core.exception.ClasspathAccessException; 018 019import de.schlichtherle.io.archive.zip.ZipEntry; 020import de.schlichtherle.util.zip.ZipFile; 021 022public class ClasspathProjector implements Projector<File> { 023 024 public static final ClasspathProjector SINGLETON = new ClasspathProjector(); 025 026 private static final Map<File, List<File>> PROJECTION_CACHE = new HashMap<File, List<File>>(); 027 028 public ClasspathProjector() { 029 // TODO Preload the projection cache if possible 030 } 031 032 @Override 033 public List<File> project(File segment) { 034 035 List<File> files = PROJECTION_CACHE.get(segment); 036 if (files != null) { 037 return files; 038 } 039 040 files = new ArrayList<File>(); 041 boolean isArchive = false; 042 043 if (segment instanceof de.schlichtherle.io.File) { 044 if (((de.schlichtherle.io.File)segment).isArchive()) { 045 isArchive = true; 046 } 047 } 048 049// if (segment.toString().startsWith(System.getProperty("java.home"))) { 050// String cacheFileKey = buildFileKey(segment); 051// ClassLoader[] classLoaders = ClassLoaderUtils.getClassLoaders(); 052// 053// for (ClassLoader cl : classLoaders) { 054// 055// InputStream is = null; 056// InputStreamReader isr = null; 057// BufferedReader br = null; 058// try { 059// is = cl.getResourceAsStream(cacheFileKey); 060// if (is != null) { 061// isr = new InputStreamReader(is); 062// br = new BufferedReader(isr, 16384); 063// String nextLine; 064// try { 065// while ((nextLine = br.readLine()) != null) { 066// files.add(new de.schlichtherle.io.File(segment.getPath() + System.getProperty("file.separator") + nextLine)); 067// } 068// } catch (IOException e) { 069// throw new ClasspathAccessException("Could not open Cached File List: " + e.getMessage(), e); 070// } 071// PROJECTION_CACHE.put(segment, files); 072// return files; 073// } 074// } finally { 075// if (is != null) { 076// try { 077// is.close(); 078// } catch (IOException e) { 079// } 080// } 081// if (isr != null) { 082// try { 083// isr.close(); 084// } catch (IOException e) { 085// } 086// } 087// if (br != null) { 088// try { 089// br.close(); 090// } catch (IOException e) { 091// } 092// } 093// } 094// } 095// projectCachedJavaHome(segment); 096// } 097 098 if (!isArchive) { 099 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}