package br.com.ingenieux.launchify.core;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.vfs2.AllFileSelector;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSelector;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileSystemManager;
import org.apache.commons.vfs2.FileType;
import org.apache.commons.vfs2.VFS;
import org.objectweb.asm.ClassReader;
import br.com.ingenieux.launchify.core.spi.LaunchifyVisitor;
public class Scanner {
private static final FileSelector CLASS_FILE_SELECTOR = new AllFileSelector() {
public boolean includeFile(
org.apache.commons.vfs2.FileSelectInfo fileInfo) {
FileObject file = fileInfo.getFile();
String baseName = file.getName().getBaseName();
try {
boolean topClassFile = file.getType().equals(FileType.FILE)
&& baseName.endsWith(".class")
&& (-1 == baseName.indexOf('$'));
boolean childDirectory = file.getType().equals(FileType.FOLDER);
return topClassFile || childDirectory;
} catch (FileSystemException e) {
throw new RuntimeException(e);
}
};
};
List<String> rootDirectories = new ArrayList<String>();
public Scanner() {
}
public Scanner(String... args) {
this.setRootDirectories(Arrays.asList(args));
}
public Collection<String> getRootDirectories() {
return this.rootDirectories;
}
public void setRootDirectories(Collection<String> rootDirectories) {
this.rootDirectories = new ArrayList<String>(rootDirectories);
}
public Collection<ApplicationEntry> getApplicationEntries()
throws Exception {
Set<ApplicationEntry> results = new LinkedHashSet<ApplicationEntry>();
FileSystemManager manager = VFS.getManager();
for (String rootDirectory : rootDirectories) {
FileObject rootFileObject = manager.resolveFile(rootDirectory);
List<FileObject> foundFiles = new ArrayList<FileObject>();
rootFileObject.findFiles(CLASS_FILE_SELECTOR, true, foundFiles);
for (FileObject obj : foundFiles) {
if (!obj.getType().equals(FileType.FILE))
continue;
ClassReader classReader = new ClassReader(obj.getContent()
.getInputStream());
LaunchifyVisitor visitor = new LaunchifyVisitor();
classReader.accept(visitor, ClassReader.SKIP_CODE
| ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
if (visitor.isValid()) {
ApplicationEntry entry = new ApplicationEntry();
entry.setName(visitor.getAppName());
entry.setClassName(visitor.getClassName());
results.add(entry);
}
}
}
return results;
}
}