Java tutorial
package com.extjs; import jargs.gnu.CmdLineParser; import java.io.File; import java.io.*; import java.io.FilenameFilter; import java.util.regex.*; import java.util.*; import org.json.*; import java.util.ArrayList; import com.yahoo.platform.yui.compressor.*; import org.mozilla.javascript.*; public class JSBuilder2 { private static String version = "2.0.0"; private static ArrayList<File> outputFiles = new ArrayList<File>(); private static String homeDir; private static String projectFile; private static String debugSuffix; private static JSONObject projCfg; private static JSONArray pkgs; private static Boolean verbose; private static File deployDir; private static File headerFile; private static String projectHome; public static void main(String[] args) { if (!parseArgs(args)) { printUsage(); } else { openProjectFile(projectFile); createTempHeaderFile(); loadPackages(); mkDeployDir(); createTargetsWithFileIncludes(); createTargetsWithDeps(); copyResources(); writeHeadersToTargets(); compressOutputFiles(); } } private static void printUsage() { System.out.println("JSBuilder version " + version); System.out.println("Ext JS, LLC."); System.out.println("\nAvailable arguments:"); System.out.println(" --projectFile -p (REQUIRED) Location of a jsb2 project file"); System.out.println(" --homeDir -d (REQUIRED) Home directory to build the project to"); System.out .println(" --verbose -v (OPTIONAL) Output detailed information about what is being built"); System.out.println( " --debugSuffix -s (OPTIONAL) Suffix to append to JS debug targets, defaults to \'debug\'"); System.out.println(" --help -h (OPTIONAL) Prints this help display."); System.out.println("\nExample Usage:"); System.out.println("Windows:"); System.out.println( "java -jar JSBuilder2.jar --projectFile C:\\Apps\\www\\ext3svn\\ext.jsb2 --homeDir C:\\Apps\\www\\deploy\\"); System.out.println("Linux and OS X:"); System.out.println( "java -jar JSBuilder2.jar --projectFile /home/aaron/www/trunk/ext.jsb2 --homeDir /home/aaron/www/deploy/"); System.out.println("\nJSBuilder2 is a JavaScript and CSS project build tool."); System.out.println("For additional information, see http://extjs.com/products/jsbuilder/"); } private static boolean parseArgs(String[] args) { CmdLineParser parser = new CmdLineParser(); CmdLineParser.Option projectFileOpt = parser.addStringOption('p', "projectFile"); CmdLineParser.Option homeDirOpt = parser.addStringOption('d', "homeDir"); CmdLineParser.Option verboseOpt = parser.addBooleanOption('v', "verbose"); CmdLineParser.Option helpOpt = parser.addBooleanOption('h', "help"); CmdLineParser.Option debugSuffixOpt = parser.addStringOption('s', "debugSuffix"); try { parser.parse(args); } catch (CmdLineParser.OptionException e) { System.err.println(e.getMessage()); System.exit(2); } homeDir = (String) parser.getOptionValue(homeDirOpt, ""); projectFile = (String) parser.getOptionValue(projectFileOpt, ""); debugSuffix = (String) parser.getOptionValue(debugSuffixOpt, "-debug"); verbose = (Boolean) parser.getOptionValue(verboseOpt, false); Boolean help = (Boolean) parser.getOptionValue(helpOpt, false); // if help dont proceed if (help) { return false; } if (homeDir.equals("")) { System.err.println( "The --homeDir or -d argument is required and was not included in the commandline arguments."); } if (projectFile.equals("")) { System.err.println( "The --projectFile or -p argument is required and was not included in the commandline arguments."); } return !(homeDir.equals("") || projectFile.equals("")); } private static void openProjectFile(String projectFileName) { try { System.out.println(projectFileName); File inputFile = new File(projectFileName); projectHome = inputFile.getAbsoluteFile().getParent(); /* read the file into a string */ String s = FileHelper.readFileToString(inputFile); /* create json obj from string */ projCfg = new JSONObject(s); System.out.format("Loading the '%s' Project%n", projCfg.get("projectName")); } catch (Exception e) { System.err.println(e.getMessage()); System.err.println("Failed to open project file."); } } private static void loadPackages() { try { pkgs = projCfg.getJSONArray("pkgs"); System.out.format("Loaded %d Packages%n", pkgs.length()); } catch (Exception e) { System.err.println(e.getMessage()); System.err.println("Failed to find 'pkgs' configuration."); } } private static void createTempHeaderFile() { try { StringBuilder headerBuilder = new StringBuilder(); headerFile = File.createTempFile("header", ".hd"); headerFile.deleteOnExit(); String licText = projCfg.getString("licenseText"); String[] licTextArray = licText.split("\n"); headerBuilder.append("/*!\n"); for (String line : licTextArray) { headerBuilder.append(" * "); headerBuilder.append(line); headerBuilder.append("\n"); } headerBuilder.append(" */\n"); FileHelper.writeStringToFile(headerBuilder.toString(), headerFile, false); } catch (Exception e) { e.printStackTrace(); System.err.println("Failed to create temporary header file."); } } private static void mkDeployDir() { try { deployDir = new File(homeDir + File.separatorChar + projCfg.getString("deployDir")); deployDir.mkdirs(); } catch (Exception e) { System.err.println(e.getMessage()); System.err.println("Failed to create deploy directory."); } } private static void createTargetsWithFileIncludes() { try { int len = pkgs.length(); /* loop over packages for fileIncludes */ for (int i = 0; i < len; i++) { /* Build pkg and include file deps */ JSONObject pkg = pkgs.getJSONObject(i); /* if we don't include dependencies, it must be fileIncludes */ if (!pkg.optBoolean("includeDeps", false)) { String targFileName = pkg.getString("file"); if (targFileName.contains(".js")) { targFileName = FileHelper.insertFileSuffix(pkg.getString("file"), debugSuffix); } if (verbose) { System.out.format("Building the '%s' package as '%s'%n", pkg.getString("name"), targFileName); } /* create file and write out header */ File targetFile = new File(deployDir.getCanonicalPath() + File.separatorChar + targFileName); outputFiles.add(targetFile); targetFile.getParentFile().mkdirs(); FileHelper.writeStringToFile("", targetFile, false); /* get necessary file includes for this specific package */ JSONArray fileIncludes = pkg.getJSONArray("fileIncludes"); int fileIncludesLen = fileIncludes.length(); if (verbose) { System.out.format("- There are %d file include(s).%n", fileIncludesLen); } /* loop over file includes */ for (int j = 0; j < fileIncludesLen; j++) { /* open each file, read into string and append to target */ JSONObject fileCfg = fileIncludes.getJSONObject(j); String subFileName = projectHome + File.separatorChar + fileCfg.getString("path") + fileCfg.getString("text"); if (verbose) { System.out.format("- - %s%s%n", fileCfg.getString("path"), fileCfg.getString("text")); } File subFile = new File(subFileName); String tempString = FileHelper.readFileToString(subFile); FileHelper.writeStringToFile(tempString, targetFile, true); } } } } catch (Exception e) { System.err.println(e.getMessage()); System.err.println("Failed to create targets with fileIncludes."); } } private static void createTargetsWithDeps() { try { int len = pkgs.length(); for (int i = 0; i < len; i++) { /* Build pkg and include file deps */ JSONObject pkg = pkgs.getJSONObject(i); /* if we need to includeDeps, they shoudl already be built. */ if (pkg.optBoolean("includeDeps", false)) { String targFileName = pkg.getString("file"); if (targFileName.contains(".js")) { targFileName = FileHelper.insertFileSuffix(pkg.getString("file"), debugSuffix); } if (verbose) { System.out.format("Building the '%s' package as '%s'%n", pkg.getString("name"), targFileName); System.out.println("This package is built by included dependencies."); } /* create file and write out header */ File targetFile = new File(deployDir.getCanonicalPath() + File.separatorChar + targFileName); outputFiles.add(targetFile); targetFile.getParentFile().mkdirs(); FileHelper.writeStringToFile("", targetFile, false); /* get necessary pkg includes for this specific package */ JSONArray pkgDeps = pkg.getJSONArray("pkgDeps"); int pkgDepsLen = pkgDeps.length(); if (verbose) { System.out.format("- There are %d package include(s).%n", pkgDepsLen); } /* loop over file includes */ for (int j = 0; j < pkgDepsLen; j++) { /* open each file, read into string and append to target */ String pkgDep = pkgDeps.getString(j); if (verbose) { System.out.format("- - %s%n", pkgDep); } String nameWithorWithoutSuffix = pkgDep; if (pkgDep.contains(".js")) { nameWithorWithoutSuffix = FileHelper.insertFileSuffix(pkgDep, debugSuffix); } String subFileName = deployDir.getCanonicalPath() + File.separatorChar + nameWithorWithoutSuffix; File subFile = new File(subFileName); String tempString = FileHelper.readFileToString(subFile); FileHelper.writeStringToFile(tempString, targetFile, true); } } } } catch (Exception e) { e.printStackTrace(); System.err.println("Failed to create target with package dependencies."); } } public static void writeHeadersToTargets() { Collection<File> outFiles = FileHelper.listFiles(deployDir, new FilenameFilter() { private Pattern pattern = Pattern.compile(".*[\\.js|\\.css]"); public boolean accept(File dir, String name) { return pattern.matcher(name).matches() && !(new File(dir.getAbsolutePath() + File.separatorChar + name).isDirectory()); } }, true); for (File f : outFiles) { String headerContents = FileHelper.readFileToString(headerFile); String codeContents = FileHelper.readFileToString(f); FileHelper.writeStringToFile(headerContents, f, false); FileHelper.writeStringToFile(codeContents, f, true); } } public static void compressOutputFiles() { Reader in = null; Writer out = null; System.out.println("Compressing output files..."); for (File f : outputFiles) { try { if (f.getName().contains(".js")) { if (verbose) { System.out.println("- - " + f.getName() + " -> " + f.getName().replace(debugSuffix, "")); } in = new InputStreamReader(new FileInputStream(f)); JavaScriptCompressor compressor = new JavaScriptCompressor(in, new ErrorReporter() { public void warning(String message, String sourceName, int line, String lineSource, int lineOffset) { if (line < 0) { System.err.println("\n[WARNING] " + message); } else { System.err.println("\n[WARNING] " + line + ':' + lineOffset + ':' + message); } } public void error(String message, String sourceName, int line, String lineSource, int lineOffset) { if (line < 0) { System.err.println("\n[ERROR] " + message); } else { System.err.println("\n[ERROR] " + line + ':' + lineOffset + ':' + message); } } public EvaluatorException runtimeError(String message, String sourceName, int line, String lineSource, int lineOffset) { error(message, sourceName, line, lineSource, lineOffset); return new EvaluatorException(message); } }); // Close the input stream first, and then open the output stream, // in case the output file should override the input file. in.close(); in = null; out = new OutputStreamWriter( new FileOutputStream(f.getAbsolutePath().replace(debugSuffix, ""))); boolean munge = true; boolean preserveAllSemiColons = false; boolean disableOptimizations = false; int linebreakpos = -1; compressor.compress(out, linebreakpos, munge, false, preserveAllSemiColons, disableOptimizations); } } catch (EvaluatorException e) { e.printStackTrace(); // Return a special error code used specifically by the web front-end. System.exit(2); } catch (IOException e) { e.printStackTrace(); System.exit(1); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } } public static void copyResources() { try { JSONArray resources = projCfg.getJSONArray("resources"); int resourceLen = resources.length(); for (int z = 0; z < resourceLen; z++) { JSONObject resourceCfg = resources.getJSONObject(z); String filters = resourceCfg.getString("filters"); File srcDir = new File(projectHome + File.separatorChar + resourceCfg.getString("src")); File destDir = new File( deployDir.getCanonicalPath() + File.separatorChar + resourceCfg.getString("dest")); FileHelper.copyDirectory(srcDir, destDir, filters); } } catch (Exception e) { e.printStackTrace(); } } }