public void begin(String namespace, String name, Attributes attributes) throws Exception {
   String className = attributes.getValue("type");
   if (className != null) {
     ModuleConfig mc = (ModuleConfig) digester.peek();
     mc.setActionForwardClass(className);
   }
 }
Example #2
0
  @Override
  protected void doGet(HttpExchange exchange, QueryData data, Config config) throws IOException {
    Compilation compilation = getCompilation(exchange, data, config);
    if (compilation == null) {
      return;
    }
    if (!compilation.usesModules()) {
      HttpUtil.writeErrorMessageResponse(exchange, "This configuration does not use modules");
      return;
    }

    // Get the size of each module.
    ModuleConfig moduleConfig = config.getModuleConfig();
    Map<String, List<String>> invertedDependencyTree = moduleConfig.getInvertedDependencyTree();
    Function<String, String> moduleNameToUri = moduleConfig.createModuleNameToUriFunction();
    ImmutableMap.Builder<String, Pair<Integer, Integer>> builder = ImmutableMap.builder();
    final boolean isDebugMode = false;
    for (String module : invertedDependencyTree.keySet()) {
      // The file size is in bytes, assuming UTF-8 input.
      String compiledCode = compilation.getCodeForModule(module, isDebugMode, moduleNameToUri);
      int uncompressedSize = compiledCode.getBytes(Charsets.UTF_8).length;
      int gzippedSize = GzipUtil.getGzipSize(compiledCode);
      builder.put(module, Pair.of(uncompressedSize, gzippedSize));
    }
    Map<String, Pair<Integer, Integer>> moduleSizes = builder.build();

    // Construct the SVG.
    SetMultimap<Integer, String> moduleDepths =
        calculateModuleDepths(moduleConfig.getRootModule(), invertedDependencyTree);
    Map<String, List<JsInput>> moduleToInputs;
    try {
      moduleToInputs = moduleConfig.partitionInputsIntoModules(config.getManifest());
    } catch (CompilationException e) {
      throw new RuntimeException(e);
    }
    Pair<String, Dimension> svg =
        generateSvg(
            config.getId(), moduleDepths, invertedDependencyTree, moduleSizes, moduleToInputs);

    // Populate Soy template.
    Dimension svgDimension = svg.getSecond();
    SoyMapData mapData =
        new SoyMapData(
            ImmutableMap.<String, Object>builder()
                .put("configId", config.getId())
                .put("svg", svg.getFirst())
                .put("svgWidth", svgDimension.width)
                .put("svgHeight", svgDimension.height)
                .build());
    String xhtml = TOFU.newRenderer("org.plovr.modules").setData(mapData).render();

    // Write the response.
    Headers responseHeaders = exchange.getResponseHeaders();
    responseHeaders.set("Content-Type", "text/xml");
    exchange.sendResponseHeaders(200, xhtml.length());
    Writer responseBody = new OutputStreamWriter(exchange.getResponseBody());
    responseBody.write(xhtml);
    responseBody.close();
  }
  public boolean raisesWarning() {
    if (!calculated) getPercentages();

    for (int i = 0; i < lowerQuartile.length; i++) {
      if (lowerQuartile[i] < ModuleConfig.getParam("quality_base_lower", "warn")
          || medians[i] < ModuleConfig.getParam("quality_base_median", "warn")) {
        return true;
      }
    }
    return false;
  }
Example #4
0
 /**
  * Creates the JSON needed to define the PLOVR_MODULE_INFO variable.
  *
  * @param moduleConfig
  */
 static JsonObject createModuleInfo(ModuleConfig moduleConfig) {
   JsonObject obj = new JsonObject();
   for (String moduleName : moduleConfig.getModuleNames()) {
     JsonArray modulesThatMustBeLoadedFirst = new JsonArray();
     for (String module : moduleConfig.getModuleInfo(moduleName).getDeps()) {
       modulesThatMustBeLoadedFirst.add(new JsonPrimitive(module));
     }
     obj.add(moduleName, modulesThatMustBeLoadedFirst);
   }
   return obj;
 }
Example #5
0
  @Override
  protected void doGet(HttpExchange exchange, QueryData data, Config config) throws IOException {
    Compilation compilation = getCompilation(exchange, data, config);
    if (compilation == null) {
      return;
    }

    String configId = config.getId();
    List<JsInput> inputs;
    if (compilation.usesModules()) {
      ModuleConfig moduleConfig = config.getModuleConfig();
      Map<String, List<JsInput>> moduleToInputs;
      try {
        moduleToInputs = moduleConfig.partitionInputsIntoModules(config.getManifest());
      } catch (CompilationException e) {
        throw new RuntimeException(e);
      }

      String module = data.getParam("module");
      inputs = moduleToInputs.get(module);
    } else {
      try {
        inputs = config.getManifest().getInputsInCompilationOrder();
      } catch (CompilationException e) {
        HttpUtil.writeErrorMessageResponse(exchange, e.getMessage());
        return;
      }
    }

    // Build up the list of hyperlinks.
    Function<JsInput, String> converter =
        InputFileHandler.createInputNameToUriConverter(server, exchange, configId);
    SoyListData inputData = new SoyListData();
    for (JsInput input : inputs) {
      SoyMapData inputDatum = new SoyMapData();
      inputDatum.put("href", converter.apply(input));
      inputDatum.put("name", input.getName());
      inputData.add(inputDatum);
    }
    SoyMapData soyData = new SoyMapData();
    soyData.put("inputs", inputData);
    soyData.put("configId", configId);

    // Write the response.
    Headers responseHeaders = exchange.getResponseHeaders();
    responseHeaders.set("Content-Type", "text/html");
    String html = TOFU.newRenderer("org.plovr.list").setData(soyData).render();
    exchange.sendResponseHeaders(200, html.length());
    Writer responseBody = new OutputStreamWriter(exchange.getResponseBody());
    responseBody.write(html);
    responseBody.close();
  }
 public boolean ignoreInReport() {
   // We don't show this if there is no quality data.
   if (ModuleConfig.getParam("quality_base", "ignore") > 0 || qualityCounts.length == 0) {
     return true;
   }
   return false;
 }
Example #7
0
 /** Creates the JSON needed to define the PLOVR_MODULE_URIS variable. */
 static JsonObject createModuleUris(
     ModuleConfig moduleConfig, Function<String, String> moduleNameToUri) {
   JsonObject obj = new JsonObject();
   for (String moduleName : moduleConfig.getModuleNames()) {
     obj.addProperty(moduleName, moduleNameToUri.apply(moduleName));
   }
   return obj;
 }
  /** Basic check that shouldn't detect an error. */
  public void testCheckCircularInheritance() {
    FormBeanConfig child = new FormBeanConfig();

    child.setName("child");
    child.setExtends("baseForm");

    FormBeanConfig grandChild = new FormBeanConfig();

    grandChild.setName("grandChild");
    grandChild.setExtends("child");

    config.addFormBeanConfig(child);
    config.addFormBeanConfig(grandChild);

    assertTrue(
        "Circular inheritance shouldn't have been detected",
        !grandChild.checkCircularInheritance(config));
  }
  public Object createObject(Attributes attributes) {

    // Identify the name of the class to instantiate
    String className = attributes.getValue("className");
    if (className == null) {
      ModuleConfig mc = (ModuleConfig) digester.peek(1);
      className = mc.getActionForwardClass();
    }

    // Instantiate the new object and return it
    Object actionForward = null;
    try {
      actionForward = RequestUtils.applicationInstance(className);
    } catch (Exception e) {
      digester.getLogger().error("ActionForwardFactory.createObject: ", e);
    }

    return actionForward;
  }
  /** Test that processExtends() makes sure that a base form's own extension has been processed. */
  public void testProcessExtendsBaseFormExtends() throws Exception {
    CustomFormBeanConfig first = new CustomFormBeanConfig();

    first.setName("first");

    CustomFormBeanConfig second = new CustomFormBeanConfig();

    second.setName("second");
    second.setExtends("first");

    config.addFormBeanConfig(first);
    config.addFormBeanConfig(second);

    // set baseForm to extend second
    baseForm.setExtends("second");

    baseForm.processExtends(config);

    assertTrue("The first form's processExtends() wasn't called", first.processExtendsCalled);
    assertTrue("The second form's processExtends() wasn't called", second.processExtendsCalled);
  }
  /** Basic check that SHOULD detect an error. */
  public void testCheckCircularInheritanceError() {
    FormBeanConfig child = new FormBeanConfig();

    child.setName("child");
    child.setExtends("baseForm");

    FormBeanConfig grandChild = new FormBeanConfig();

    grandChild.setName("grandChild");
    grandChild.setExtends("child");

    // establish the circular relationship with base
    baseForm.setExtends("grandChild");

    config.addFormBeanConfig(child);
    config.addFormBeanConfig(grandChild);

    assertTrue(
        "Circular inheritance should've been detected",
        grandChild.checkCircularInheritance(config));
  }
  /** Set up instance variables required by this test case. */
  public void setUp() {
    ModuleConfigFactory factoryObject = ModuleConfigFactory.createFactory();

    config = factoryObject.createModuleConfig("");

    // setup the base form
    baseForm = new FormBeanConfig();
    baseForm.setName("baseForm");
    baseForm.setType("org.apache.struts.action.DynaActionForm");

    // set up id, name, and score
    FormPropertyConfig property = new FormPropertyConfig();

    property.setName("id");
    property.setType("java.lang.String");
    baseForm.addFormPropertyConfig(property);

    property = new FormPropertyConfig();
    property.setName("name");
    property.setType("java.lang.String");
    property.setProperty("count", "10");
    baseForm.addFormPropertyConfig(property);

    property = new FormPropertyConfig();
    property.setName("score");
    property.setType("java.lang.String");
    baseForm.addFormPropertyConfig(property);

    property = new FormPropertyConfig();
    property.setName("message");
    property.setType("java.lang.String");
    baseForm.addFormPropertyConfig(property);

    // register it to our config
    config.addFormBeanConfig(baseForm);
  }
  /**
   * Test a typical form bean configuration extension where various properties should be inherited
   * from a base form. This method checks all the properties.
   */
  public void testInheritFrom() throws Exception {
    // give baseForm some arbitrary parameters
    String baseFormCount = "1";

    baseForm.setProperty("count", baseFormCount);

    // create a basic subform
    FormBeanConfig subForm = new FormBeanConfig();
    String subFormName = "subForm";

    subForm.setName(subFormName);
    subForm.setExtends("baseForm");

    // override score
    FormPropertyConfig property = new FormPropertyConfig();

    property.setName("score");
    property.setType("java.lang.Integer");
    subForm.addFormPropertyConfig(property);

    // ... and id
    property = new FormPropertyConfig();
    property.setName("id");
    property.setType("java.lang.String");
    property.setInitial("unknown");
    subForm.addFormPropertyConfig(property);

    // ... and message
    property = new FormPropertyConfig();
    property.setName("message");
    property.setType("java.lang.String");
    property.setSize(10);
    subForm.addFormPropertyConfig(property);

    config.addFormBeanConfig(subForm);

    subForm.inheritFrom(baseForm);

    // check that our subForm is still the one in the config
    assertSame("subForm no longer in ModuleConfig", subForm, config.findFormBeanConfig("subForm"));

    // check our configured sub form
    assertNotNull("Form bean type was not inherited", subForm.getType());
    assertEquals("Wrong form bean name", subFormName, subForm.getName());
    assertEquals("Wrong form bean type", baseForm.getType(), subForm.getType());
    assertEquals("Wrong restricted value", baseForm.isRestricted(), subForm.isRestricted());

    FormPropertyConfig[] formPropertyConfigs = subForm.findFormPropertyConfigs();

    assertEquals("Wrong prop count", 4, formPropertyConfigs.length);

    // we want to check that the form is EXACTLY as we want it, so
    //  here are some fine grain checks
    property = subForm.findFormPropertyConfig("name");

    FormPropertyConfig original = baseForm.findFormPropertyConfig("name");

    assertNotNull("'name' property was not inherited", property);
    assertEquals("Wrong type for name", original.getType(), property.getType());
    assertEquals("Wrong initial value for name", original.getInitial(), property.getInitial());
    assertEquals("Wrong size value for name", original.getSize(), property.getSize());

    property = subForm.findFormPropertyConfig("id");
    original = baseForm.findFormPropertyConfig("id");
    assertNotNull("'id' property was not found", property);
    assertEquals("Wrong type for id", original.getType(), property.getType());
    assertEquals("Wrong initial value for id", "unknown", property.getInitial());
    assertEquals("Wrong size value for id", original.getSize(), property.getSize());

    property = subForm.findFormPropertyConfig("score");
    original = baseForm.findFormPropertyConfig("score");
    assertNotNull("'score' property was not found", property);
    assertEquals("Wrong type for score", "java.lang.Integer", property.getType());
    assertEquals("Wrong initial value for score", original.getInitial(), property.getInitial());
    assertEquals("Wrong size value for score", original.getSize(), property.getSize());

    property = subForm.findFormPropertyConfig("message");
    original = baseForm.findFormPropertyConfig("message");
    assertNotNull("'message' property was not found", property);
    assertEquals("Wrong type for message", original.getType(), property.getType());
    assertEquals("Wrong initial value for message", original.getInitial(), property.getInitial());
    assertEquals("Wrong size value for message", 10, property.getSize());

    property = subForm.findFormPropertyConfig("name");
    original = baseForm.findFormPropertyConfig("name");
    assertEquals(
        "Arbitrary property not found",
        original.getProperty("count"),
        property.getProperty("count"));

    String count = subForm.getProperty("count");

    assertEquals("Arbitrary property was not inherited", baseFormCount, count);
  }
Example #14
0
  /**
   * Writes out all of the module files. This method is only applicable when modules are used. This
   * is expected to be used only with the build command.
   *
   * @throws IOException
   */
  public void writeCompiledCodeToFiles(
      final Function<String, String> moduleNameToUri, String sourceMapPath) throws IOException {
    if (modules == null) {
      throw new IllegalStateException("This compilation does not use modules");
    }

    ModuleConfig moduleConfig = config.getModuleConfig();
    Map<String, File> moduleToOutputPath = moduleConfig.getModuleToOutputPath();
    final Map<String, String> moduleNameToFingerprint = Maps.newHashMap();
    final boolean isDebugMode = false;
    for (JSModule module : modules) {
      String moduleName = module.getName();
      File outputFile = moduleToOutputPath.get(moduleName);
      com.google.common.io.Files.createParentDirs(outputFile);

      // Reset the source map if it is not going to be reset later in this
      // loop
      // when the source map is written to disk.
      final boolean resetSourceMap = (sourceMapPath == null);
      String moduleCode =
          getCodeForModule(moduleName, isDebugMode, moduleNameToUri, resetSourceMap);

      // Fingerprint the file, if appropriate.
      if (config.shouldFingerprintJsFiles()) {
        String fileName = outputFile.getName();
        String fingerprint = Md5Util.hashJs(moduleCode);
        moduleNameToFingerprint.put(moduleName, fingerprint);
        fileName = insertFingerprintIntoName(fileName, fingerprint);
        outputFile = new File(outputFile.getParentFile(), fileName);
      }

      Files.write(moduleCode, outputFile);

      // It turns out that the SourceMap will not be populated until after
      // the
      // Compiler's internal representation has been output as source
      // code, so
      // it should only be written out to a file after the compiled code
      // has
      // been generated.
      if (sourceMapPath != null) {
        Writer writer = Streams.createFileWriter(sourceMapPath + "_" + moduleName, config);
        // This is safe because getCodeForModule() was just called,
        // which has
        // the side-effect of calling compiler.toSource(module).
        SourceMap sourceMap = compiler.getSourceMap();
        sourceMap.appendTo(writer, moduleName);
        sourceMap.reset();
        Closeables.close(writer, false);
      }
    }

    if (moduleConfig.excludeModuleInfoFromRootModule()) {
      File outputFile = moduleConfig.getModuleInfoPath();
      com.google.common.io.Files.createParentDirs(outputFile);

      final Function<String, String> fingerprintedModuleNameToUri =
          new Function<String, String>() {
            @Override
            public String apply(String moduleName) {
              String uri = moduleNameToUri.apply(moduleName);
              String fingerprint = moduleNameToFingerprint.get(moduleName);
              if (fingerprint != null) {
                uri = insertFingerprintIntoName(uri, fingerprint);
              }
              return uri;
            }
          };

      Writer writer = Streams.createFileWriter(outputFile, config);
      appendRootModuleInfo(writer, isDebugMode, fingerprintedModuleNameToUri);
      Closeables.close(writer, false);
    }
  }
Example #15
0
  /**
   * This method always calls compiler.toSource(module), which means that it can be followed by a
   * call to compiler.getSourceMap().appendTo(writer, module), though
   * compiler.getSourceMap().reset() should be called immediately after when that is the case.
   *
   * <p>This method is sychronized in order to fix
   * http://code.google.com/p/plovr/issues/detail?id=31. The problem is that if two modules are
   * requested at the same time, it is often the case that compiler.toSource(module) is executing
   * for the second module while the source map is still being modified for the first module,
   * causing an IllegalStateException. Empirically, synchronizing this method appears to fix things,
   * though a more provably correct (and minimal) solution should be sought.
   */
  private synchronized String getCodeForModule(
      String moduleName,
      boolean isDebugMode,
      Function<String, String> moduleNameToUri,
      boolean resetSourceMap) {
    Preconditions.checkState(hasResult(), "Code has not been compiled yet");
    Preconditions.checkState(modules != null, "This compilation does not use modules");

    StringBuilder builder = new StringBuilder();
    ModuleConfig moduleConfig = config.getModuleConfig();
    String rootModule = moduleConfig.getRootModule();

    boolean isRootModule = rootModule.equals(moduleName);

    if (isRootModule) {
      // For the root module, prepend the following global variables:
      //
      // PLOVR_MODULE_INFO
      // PLOVR_MODULE_URIS
      // PLOVR_MODULE_USE_DEBUG_MODE
      //
      // Because the standard way to read these variables in the
      // application is:
      //
      // moduleLoader.setDebugMode(!!goog.global['PLOVR_MODULE_USE_DEBUG_MODE']);
      // moduleManager.setLoader(moduleLoader);
      // moduleManager.setAllModuleInfo(goog.global['PLOVR_MODULE_INFO']);
      // moduleManager.setModuleUris(goog.global['PLOVR_MODULE_URIS']);
      //
      // It is important that the PLOVR variables are guaranteed to be
      // global,
      // which (as much as it pains me) is why "var" is omitted.
      if (!moduleConfig.excludeModuleInfoFromRootModule()) {
        try {
          appendRootModuleInfo(builder, isDebugMode, moduleNameToUri);
        } catch (IOException e) {
          // This should not occur because data is being appended to
          // an
          // in-memory StringBuilder rather than a file.
          throw new RuntimeException(e);
        }
      }
    }

    int lineOffset = 0;

    JSModule module = nameToModule.get(moduleName);

    StringBuffer prependBuffer = new StringBuffer();
    if (isRootModule) {
      lineOffset++; // one line for the function wrapper
      for (File prepend : config.getPrependInputs()) {
        try {
          String s = Files.toString(prepend);
          if (s != null) {
            String[] lines = s.split("\n");
            for (String line : lines) {
              prependBuffer.append(line);
              prependBuffer.append("\n");
              lineOffset++;
            }
          }
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    compiler.setPrependedLineOffset(lineOffset);
    String moduleCode = compiler.toSource(module);

    boolean hasGlobalScopeName =
        !Strings.isNullOrEmpty(config.getGlobalScopeName())
            && config.getCompilationMode() != CompilationMode.WHITESPACE;

    // Optionally wrap the module in an anonymous function, with the
    // requisite wrapper to make it work.
    if (hasGlobalScopeName) {
      if (isRootModule) {
        builder.append(prependBuffer.toString());
        // Initialize the global scope in the root module.
        builder.append(config.getGlobalScopeName());
        builder.append("={};");
      }
      builder.append("(function(");
      builder.append(Config.GLOBAL_SCOPE_NAME);
      // Including a newline makes the offset into the source map easier to calculate.
      builder.append("){\n");
    }
    builder.append(moduleCode);
    if (hasGlobalScopeName) {
      builder.append("})(");
      builder.append(config.getGlobalScopeName());
      builder.append(");");
    }

    if (resetSourceMap) {
      SourceMap sourceMap = compiler.getSourceMap();
      if (sourceMap != null) sourceMap.reset();
    }

    // http://code.google.com/p/closure-library/issues/detail?id=196
    // http://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
    // non-root modules are loaded with eval, give it a sourceURL for better
    // debugging
    if (!isRootModule) {
      builder.append("\n//@ sourceURL=" + moduleNameToUri.apply(moduleName));
    }

    return builder.toString();
  }