package net.ayld.facade.dependency.resolver.impl;
import java.io.IOException;
import java.util.Set;
import net.ayld.facade.component.ListenableComponent;
import net.ayld.facade.dependency.resolver.DependencyResolver;
import net.ayld.facade.event.model.SourceDependencyResolutionEndEvent;
import net.ayld.facade.event.model.SourceDependencyResolutionStartEvent;
import net.ayld.facade.model.ClassName;
import net.ayld.facade.model.SourceFile;
import net.ayld.facade.util.Tokenizer;
import net.ayld.facade.util.annotation.ThreadSafe;
import com.google.common.base.Charsets;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.io.Resources;
@ThreadSafe
public class ManualParseSourceDependencyResolver extends ListenableComponent implements DependencyResolver<SourceFile>{
@Override
public Set<ClassName> resolve(SourceFile source) throws IOException {
eventBus.post(new SourceDependencyResolutionStartEvent("resolving: " + source.physicalFile().getAbsolutePath(), this.getClass()));
final String sourceFileContent = Resources.toString(source.physicalFile().toURI().toURL(), Charsets.UTF_8);
// we can somehow select only lines starting with import so we don't need to iterate over every single line
final Set<ClassName> result = Sets.newHashSet();
for (String line : Splitter.on("\n").split(sourceFileContent)) {
// we reached class definition, no point to loop any further
String publicClassDefinition = SourceFile.PUBLIC_KEYWORD + " " + SourceFile.CLASS_KEYWORD;
if (line.startsWith(publicClassDefinition) || line.startsWith(SourceFile.CLASS_KEYWORD)) {
break;
}
if (line.startsWith(SourceFile.IMPORT_KEYWORD)) {
if (line.endsWith(SourceFile.WILDCARD_IMPORT_SUFFIX)) {
throw new IllegalArgumentException("wildcard imports: " + line + ", not currently supported");
}
final String dependency = Tokenizer.delimiter(" ").tokenize(line).lastToken()
.replaceAll(";", "") // remove semicolon at end of imports
.replaceAll("\r", ""); // remove windows newline chars
result.add(new ClassName(dependency));
}
}
eventBus.post(new SourceDependencyResolutionEndEvent("resolved: " + result, this.getClass()));
return ImmutableSet.copyOf(result);
}
@Override
public Set<ClassName> resolve(Set<SourceFile> sources) throws IOException {
final Set<ClassName> result = Sets.newHashSet();
for (SourceFile source : sources) {
result.addAll(resolve(source));
}
return result;
}
}