package com.digiarea.closurefx.build.compiler; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import com.digiarea.closure.core.IPathResolver; import com.digiarea.closure.model.Buildpath; import com.digiarea.closure.model.Source; import com.digiarea.closurefx.IConstants; import com.google.javascript.jscomp.SourceFile; import com.google.javascript.jscomp.deps.DependencyInfo; import com.google.javascript.jscomp.deps.JsFileParser; import com.google.javascript.jscomp.deps.SortedDependencies; import com.google.javascript.jscomp.deps.SortedDependencies.CircularDependencyException; public class JSBuildpathContainerResolver { private Buildpath container; private List<File> externs = new ArrayList<File>(); private List<File> sources = new ArrayList<File>(); private IPathResolver pathResolver; private SortedDependencies<DependencyInfo> deps; private List<DependencyInfo> sourceDeps = new ArrayList<DependencyInfo>(); private List<DependencyInfo> simpleDeps = new ArrayList<DependencyInfo>(); private List<DependencyInfo> closureDeps = new ArrayList<DependencyInfo>(); public JSBuildpathContainerResolver(Buildpath container, IPathResolver pathResolver) { this.container = container; this.pathResolver = pathResolver; } public List<File> getSources() { return sources; } public List<File> getExterns() { return externs; } public void getDependencies() throws CircularDependencyException { readEntries(); deps = new SortedDependencies<DependencyInfo>( new ArrayList<DependencyInfo>(closureDeps)); } private DependencyInfo getDependency(File file) { SourceFile sourceFile = SourceFile.fromFile(file.toString()); JsFileParser parser = new JsFileParser(null); try { return parser.parseFile(sourceFile.getName(), null, sourceFile.getCode()); } catch (IOException e) { e.printStackTrace(); return null; } } public void resolve() { for (DependencyInfo dependencyInfo : simpleDeps) { sources.add(new File(dependencyInfo.getName())); } List<DependencyInfo> infos = deps.getDependenciesOf(sourceDeps, false); for (DependencyInfo dependencyInfo : infos) { sources.add(new File(dependencyInfo.getName())); } } private void readEntries() { // loop reverse for order for (int i = container.getSource().size() - 1; i >= 0; i--) { Source source = container.getSource().get(i); File file = new File(pathResolver.toRealPath(source.getPath() .toString())); readEntry(source, file); } } private List<File> readEntry(Source source, File file) { List<File> files = new ArrayList<File>(); if (file.isDirectory()) { String entries[] = file.list(); if (entries != null) { for (String entry : entries) { files.addAll(readEntry(source, new File(file, entry))); } } } else { if (file.getName().endsWith(IConstants.EXTENSION_JS)) { DependencyInfo info = getDependency(file); if (source.isExtern()) { if (source.isIncludeSimple() && info.getProvides().isEmpty()) { externs.add(file); } else if (source.isIncludeClosure()) { externs.add(file); } } else { switch (source.getEntryKind()) { case CLOSURE: // only Closure Files if (!info.getProvides().isEmpty()) { closureDeps.add(info); } else { if (info.getName() .endsWith(IConstants.CLOSURE_BASE)) { simpleDeps.add(info); } } break; case FILE: case CONTAINER: case LIBRARY: case PROJECT: case VARIABLE: if (source.isIncludeSimple() && info.getProvides().isEmpty()) { simpleDeps.add(info); } else if (source.isIncludeClosure()) { closureDeps.add(info); } break; case SOURCE: sourceDeps.add(info); closureDeps.add(info); break; } } } } return files; } }