package org.kantega.revoc.source;
import org.kantega.revoc.config.Config;
import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
/**
*
*/
public class DirectorySourceSource implements SourceSource {
private Map<String, File> sourceMap = new HashMap<String, File>();;
private Map<String, JarFile> jarFiles = new HashMap<String, JarFile>();
public DirectorySourceSource() {
String revSources = Config.getProperty("REVOC_SOURCES");
if (revSources != null) {
File revSourceDirectory = new File(revSources);
if (revSourceDirectory.exists()) {
File[] children = revSourceDirectory.listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return file.getName().endsWith(".jar");
}
});
if (children != null) {
sourceMap.putAll(parseSources(children));
}
}
}
}
private Map<String, File> parseSources(File[] files) {
HashMap<String, File> index = new HashMap<String, File>();
for (File file : files) {
JarFile jarFile = null;
try {
jarFile = new JarFile(file);
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (entry.getName().endsWith(".java")) {
index.put(entry.getName(), file);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (jarFile != null) {
try {
jarFile.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
return index;
}
@Override
public String[] getSource(String className, ClassLoader classLoader) {
try {
String sourceFileName = className.replace('.', '/') + ".java";
File file = sourceMap.get(sourceFileName);
if(file == null) {
return null;
}
JarFile jarFile = getJarFile(file);
ZipEntry entry = jarFile.getEntry(sourceFileName);
if (entry == null) {
return null;
}
InputStream inputStream = jarFile.getInputStream(entry);
List<String> lines = IOUtils.readLines(inputStream);
return lines.toArray(new String[lines.size()]);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private synchronized JarFile getJarFile(File file) {
JarFile jarFile = jarFiles.get(file.getAbsolutePath());
if(jarFile == null) {
try {
jarFiles.put(file.getAbsolutePath(), jarFile = new JarFile(file));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return jarFile;
}
}