Package org.dtk.resources.build

Source Code of org.dtk.resources.build.ProfileBuilder

package org.dtk.resources.build;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.io.FileUtils;
import org.dtk.util.FileUtil;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.Script;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.tools.shell.Global;

/**
* This class is responsible for generating custom Dojo builds by executing the existing
* JavaScript build system. Build properties are controlled using a profile file, a reference
* to which is passed in at runtime.
*
* @author James Thomas
*/

public class ProfileBuilder {
  /** Script arguments, key value pairs, which are translated to a
   * single string with key=value attributes. All arguments are used
   * to control the build scripts. */
  protected List<String> scriptArguments = new ArrayList<String>() {
    {
      add("load=build");
      add("action=release");
    }
  };
 
  /** AMD module loader script path, e.g. dojo */
  protected String moduleLoaderPath;

  /** AMD build package location */
  protected String buildPackagePath;
 
  /** Unique reference for this build, used for logging */
  protected String buildReference;
 
  /** Local AMD package descriptors format, picked up by AMD module loader */
  protected static final String djConfigPrefixFormat
    = "djConfig = {buildReference: '%1$s', packages:[{name:'build', lib:'.', location:'%2$s'}]};"
 
  protected Exception buildError;
 
  /**
   * Generate new ProfileBuilder using the arguments passed to control
   * the build process. All file paths are santised, swapping back slashes
   * encountered in Windows paths for forward slashes.
   *
   * Leaving backslashes causes numerous issues with the the build scripts on
   * the Windows platform.  
   *
   * @param profileFile - Location to profile file for this build
   * @param resultDir - Where to store the resulting build artifacts
   * @param moduleLoaderPath - Location to AMD loader package
   * @param baseUrl - Base Dojo URL being built with
   * @param buildPackagePath - AMD Builder package location
   */
  public ProfileBuilder(String profileFile, String resultDir, String moduleLoaderPath,
    String baseUrl, String buildPackagePath, String buildReference) {
    this.moduleLoaderPath = santisePath(moduleLoaderPath);
    this.buildPackagePath = santisePath(buildPackagePath);
    this.buildReference = buildReference;
   
    scriptArguments.add("profile=" + santisePath(profileFile));
    scriptArguments.add("releaseDir=" + santisePath(resultDir));
    scriptArguments.add("baseUrl=" + santisePath(baseUrl));
  }
 
  /**
   * Initiate the build process for the profile given. Will try to execute
   * the JS build system scripts for this profile, reporting whether it
   * executed successfully.
   *
   * @return Build completed successfully
   */
  public boolean executeBuild() {
    boolean buildCompleted = true;
   
    // Use Rhino's global object's as prototype for top scope because
    // logger.js assumes access to "print" function.
    Global global = new Global();
    Context cx = ContextFactory.getGlobal().enterContext();
    global.init(cx);

    // Set up standard scripts objects
    Scriptable topScope = cx.initStandardObjects(global);

    // Enforce conversion of the Java string arguments array to JavaScript native versions.
    // Leaving this as true, causes issues in the build scripts.
    cx.getWrapFactory().setJavaPrimitiveWrap(false);

    // Rhino may throw a number of exceptions due to a variety of the build errors, use generic catch to
    // get details and store for access.
    try {
      String moduleLoaderScript = readModuleLoaderSource();     
      Script moduleLoader = cx.compileString(moduleLoaderScript, "moduleLoader", 1, null);
     
      // Pretend these arguments came from the command line by stuffing them into the top context,
      // module loader expects to read them from here.
      ScriptableObject.putConstProperty(topScope, "arguments", getBuildScriptArguments());
     
      // Execute the build system scripts to generate optimised dojo builds
      moduleLoader.exec(cx, topScope)
    } catch (Exception buildError) {
      buildCompleted = false;
      this.buildError = buildError;
    }   
   
    return buildCompleted;
  }
 
  /**
   * Read AMD loader script source, with local package
   * descriptor information prefixed at the top.
   *
   * @return Module loader script source
   * @throws IOException - Unable to find module loader
   */
  protected String readModuleLoaderSource() throws IOException {
    String djConfigScriptPrefix = String.format(djConfigPrefixFormat, this.buildReference, this.buildPackagePath);
    String moduleLoaderScript = FileUtils.readFileToString(new File(this.moduleLoaderPath));
   
    return djConfigScriptPrefix + moduleLoaderScript;
  }
 
  /**
   * Return last exception captured generating a build
   * correctly.
   *
   * @return Exception - Error thrown by rhino running the build scripts
   */
  protected Exception getBuildError() {
    return buildError;
  }
 
  /**
   * Convert map of key value pairs to ordered array containing
   * arguments formated correctly, key=value key1=value1 key2=value2 etc.
   *
   * @return String[] Script arguments array
   */
  protected String[] getBuildScriptArguments() {
    return scriptArguments.toArray(new String[0]);
  }
 
  /**
   * Ensure all file paths have no backslashes, replacing
   * any found with forwardslash equivalents. This is to
   * remove problems encountered on the Windows platform.
   *
   * @param path - Path to a file we're referencing
   * @return Santised path
   */
  protected String santisePath(String path) {
    return path.replace('\\', '/');
  }
}
TOP

Related Classes of org.dtk.resources.build.ProfileBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.