| package org.apache.flex.compiler.internal.graph; |
| |
| import java.io.BufferedInputStream; |
| import java.io.BufferedOutputStream; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Scanner; |
| import java.util.Set; |
| |
| import org.apache.commons.io.FileUtils; |
| import org.apache.flex.compiler.internal.projects.DependencyGraph; |
| import org.apache.flex.compiler.units.ICompilationUnit; |
| |
| public class GoogDepsWriter { |
| |
| public GoogDepsWriter(ICompilationUnit mainCU, File outputFolder) |
| { |
| this.mainCU = mainCU; |
| this.outputFolderPath = outputFolder.getAbsolutePath(); |
| this.sourceFolderPath = mainCU.getAbsoluteFilename(); |
| File sourceFile = new File(sourceFolderPath); |
| sourceFile = sourceFile.getParentFile(); |
| this.sourceFolderPath = sourceFile.getAbsolutePath(); |
| String flexJSHome = System.getenv("FLEXJS_HOME"); |
| if (flexJSHome == null || flexJSHome.length() == 0) |
| System.out.println("FLEXJS_HOME not defined. Should point to root of FlexJS source."); |
| frameworkRoot = flexJSHome; |
| } |
| |
| private ICompilationUnit mainCU; |
| private String outputFolderPath; |
| private String sourceFolderPath; |
| |
| private HashMap<String,GoogDep> depMap = new HashMap<String,GoogDep>(); |
| |
| public ArrayList<String> getListOfFiles() throws InterruptedException |
| { |
| buildDB(); |
| String mainName = mainCU.getShortNames().get(0); |
| ArrayList<GoogDep> dps = sort(mainName); |
| ArrayList<String> files = new ArrayList<String>(); |
| for (GoogDep gd : dps) |
| { |
| files.add(gd.filePath); |
| } |
| return files; |
| } |
| |
| public void writeToStream(OutputStream outputStream) throws InterruptedException, FileNotFoundException |
| { |
| buildDB(); |
| String mainName = mainCU.getShortNames().get(0); |
| ArrayList<GoogDep> dps = sort(mainName); |
| String outString = "// generated by FalconJS" + "\n"; |
| int n = dps.size(); |
| for (int i = n - 1; i >= 0; i--) |
| { |
| GoogDep gd = dps.get(i); |
| String s = "goog.addDependency('"; |
| s += relativePath(gd.filePath); |
| s += "', ['"; |
| s += gd.className; |
| s += "'], ["; |
| s += getDependencies(gd.deps); |
| s += "]);\n"; |
| outString += s; |
| } |
| System.out.println("Assumptions:"); |
| System.out.println(" 1) Output folder has copy of goog folder from GoogleClosure/library/closure/goog"); |
| System.out.println(" 2) Output folder has copy of FlexJS source in FlexJS folder"); |
| System.out.println(" 3) Output Folder structure is:"); |
| System.out.println(" OutputFolder/"); |
| System.out.println(" goog/"); |
| System.out.println(" base.js"); |
| System.out.println(" ..."); |
| System.out.println(" flash/ (from FlexJS/src)"); |
| System.out.println(" events/ (from FlexJS/src)"); |
| System.out.println(" org/ (from FlexJS/src)"); |
| System.out.println(" apache/ (from FlexJS/src)"); |
| System.out.println(" 4) Output folder has html file of the form:"); |
| System.out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"); |
| System.out.println("<html xmlns=\"http://www.w3.org/1999/xhtml\">"); |
| System.out.println("<head>"); |
| System.out.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />"); |
| System.out.println("<script type=\"text/javascript\" src=\"goog/base.js\" ></script>"); |
| System.out.println("<script type=\"text/javascript\" src=\"" + mainName + "Deps.js" + "\" ></script>"); |
| System.out.println("<script type=\"text/javascript\">"); |
| System.out.println(" goog.require('" + mainName + "')"); |
| System.out.println("</script>"); |
| System.out.println("<script type=\"text/javascript\">"); |
| System.out.println(" var app = new " + mainName + "();"); |
| System.out.println("</script>"); |
| System.out.println("<title>" + mainName + "</title>"); |
| System.out.println("</head>"); |
| System.out.println("<body onload=\"app.start()\">"); |
| System.out.println("</body>"); |
| System.out.println("</html>"); |
| File htmlFile = new File(outputFolderPath + File.separator + mainName + ".example.html"); |
| BufferedOutputStream outputbuffer = new BufferedOutputStream(new FileOutputStream(htmlFile)); |
| String html = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"; |
| html += "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"; |
| html += "<head>\n"; |
| html += "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n"; |
| html += "<script type=\"text/javascript\" src=\"goog/base.js\" ></script>\n"; |
| html += "<script type=\"text/javascript\" src=\"" + mainName + "Deps.js" + "\" ></script>\n"; |
| html += "<script type=\"text/javascript\">\n"; |
| html += " goog.require('" + mainName + "')\n"; |
| html += "</script>\n"; |
| html += "<script type=\"text/javascript\">\n"; |
| html += " var app = new " + mainName + "();\n"; |
| html += "</script>\n"; |
| html += "<title>" + mainName + "</title>\n"; |
| html += "</head>\n"; |
| html += "<body onload=\"app.start()\">\n"; |
| html += "</body>\n"; |
| html += "</html>\n"; |
| try |
| { |
| outputbuffer.write(html.getBytes()); |
| outputbuffer.flush(); |
| outputbuffer.close(); |
| outputStream.write(outString.getBytes()); |
| } |
| catch (IOException e) |
| { |
| |
| } |
| } |
| |
| private void buildDB() |
| { |
| try { |
| addDeps(mainCU.getShortNames().get(0)); |
| } catch (InterruptedException e) { |
| // TODO Auto-generated catch block |
| e.printStackTrace(); |
| } |
| } |
| |
| private HashMap<String, GoogDep> visited = new HashMap<String, GoogDep>(); |
| |
| private ArrayList<GoogDep> sort(String rootClassName) |
| { |
| ArrayList<GoogDep> arr = new ArrayList<GoogDep>(); |
| GoogDep current = depMap.get(rootClassName); |
| sortFunction(current, arr); |
| return arr; |
| } |
| |
| private void sortFunction(GoogDep current, ArrayList<GoogDep> arr) |
| { |
| visited.put(current.className, current); |
| |
| ArrayList<String> deps = current.deps; |
| for (String className : deps) |
| { |
| if (!visited.containsKey(className)) |
| { |
| GoogDep gd = depMap.get(className); |
| sortFunction(gd, arr); |
| } |
| } |
| arr.add(current); |
| } |
| |
| private void addDeps(String className) |
| { |
| if (depMap.containsKey(className)) |
| return; |
| |
| // build goog dependency list |
| GoogDep gd = new GoogDep(); |
| gd.className = className; |
| gd.filePath = getFilePath(className); |
| depMap.put(gd.className, gd); |
| ArrayList<String> deps = getDirectDependencies(gd.filePath); |
| gd.deps = new ArrayList<String>(); |
| for (String dep : deps) |
| { |
| gd.deps.add(dep); |
| addDeps(dep); |
| } |
| } |
| |
| String frameworkRoot; |
| |
| String getFilePath(String className) |
| { |
| System.out.println("Finding file for class: " + className); |
| String classPath = className.replace(".", File.separator); |
| String fn = frameworkRoot + File.separator + classPath + ".js"; |
| File f = new File(fn); |
| if (f.exists()) |
| return fn; |
| fn = sourceFolderPath + File.separator + classPath + ".js"; |
| f = new File(fn); |
| if (f.exists()) |
| { |
| fn = outputFolderPath + File.separator + classPath + ".js"; |
| File destFile = new File(fn); |
| // copy source to output |
| try { |
| FileUtils.copyFile(f, destFile); |
| System.out.println("Copying file for class: " + className); |
| } catch (IOException e) { |
| // TODO Auto-generated catch block |
| System.out.println("Error copying file for class: " + className); |
| } |
| return fn; |
| } |
| fn = outputFolderPath + File.separator + classPath + ".js"; |
| f = new File(fn); |
| if (f.exists()) |
| return fn; |
| if (className.indexOf('.') > -1) |
| { |
| classPath = className.substring(className.lastIndexOf('.') + 1); |
| fn = outputFolderPath + File.separator + classPath + ".js"; |
| f = new File(fn); |
| if (f.exists()) |
| return fn; |
| } |
| System.out.println("Could not find file for class: " + className); |
| return ""; |
| } |
| |
| private ArrayList<String> getDirectDependencies(String fn) |
| { |
| ArrayList<String> deps = new ArrayList<String>(); |
| |
| FileInputStream fis; |
| try { |
| fis = new FileInputStream(fn); |
| Scanner scanner = new Scanner(fis, "UTF-8"); |
| while (scanner.hasNextLine()) |
| { |
| String s = scanner.nextLine(); |
| if (s.indexOf("goog.inherits") > -1) |
| break; |
| int c = s.indexOf("goog.require"); |
| if (c > -1) |
| { |
| int c2 = s.indexOf(")"); |
| s = s.substring(c + 14, c2 - 1); |
| deps.add(s); |
| } |
| } |
| } catch (FileNotFoundException e) { |
| // TODO Auto-generated catch block |
| e.printStackTrace(); |
| } |
| return deps; |
| } |
| |
| private String getDependencies(ArrayList<String> deps) |
| { |
| String s = ""; |
| for (String dep : deps) |
| { |
| if (s.length() > 0) |
| { |
| s += ", "; |
| } |
| s += "'" + dep + "'"; |
| } |
| return s; |
| } |
| |
| String relativePath(String path) |
| { |
| if (path.indexOf(frameworkRoot) == 0) |
| { |
| path = path.replace(frameworkRoot, ""); |
| } |
| else if (path.indexOf(outputFolderPath) == 0) |
| { |
| path = path.replace(outputFolderPath, ""); |
| } |
| // paths are actually URIs and always have forward slashes |
| path = path.replace('\\', '/'); |
| return ".." + path; |
| } |
| private class GoogDep |
| { |
| public String filePath; |
| public String className; |
| public ArrayList<String> deps; |
| |
| } |
| } |