Example #1
0
  /**
   * Selects a delegate template based on the rendering rules, given the delegate template name and
   * the set of active delegate package names.
   *
   * @param delTemplateName The delegate template name to select an implementation for.
   * @param activeDelPackageNames The set of active delegate package names.
   * @return The selected delegate template, or null if there are no active implementations.
   * @throws DelegateTemplateConflictException If there are two or more active implementations with
   *     equal priority (unable to select one over the other).
   */
  public TemplateDelegateNode selectDelegateTemplate(
      String delTemplateName, Set<String> activeDelPackageNames)
      throws DelegateTemplateConflictException {

    List<DelegateTemplateDivision> divisions = delTemplatesMap.get(delTemplateName);
    if (divisions == null) {
      return null;
    }

    for (DelegateTemplateDivision division : divisions) {

      TemplateDelegateNode delTemplate = null;

      for (String delPackageName : division.delPackageNameToDelTemplateMap.keySet()) {
        if (delPackageName != null && !activeDelPackageNames.contains(delPackageName)) {
          continue;
        }

        if (delTemplate != null) {
          throw new DelegateTemplateConflictException(
              String.format(
                  "For delegate template name '%s', found two active implementations with equal"
                      + " priority in delegate packages '%s' and '%s'.",
                  delTemplateName, delTemplate.getDelPackageName(), delPackageName));
        }
        delTemplate = division.delPackageNameToDelTemplateMap.get(delPackageName);
      }

      if (delTemplate != null) {
        return delTemplate;
      }
    }

    return null;
  }
Example #2
0
  /**
   * Constructor.
   *
   * @param soyTree The Soy tree from which to build a template registry.
   */
  public TemplateRegistry(SoyFileSetNode soyTree) {

    // ------ Iterate through all templates to collect data. ------

    Map<String, TemplateBasicNode> tempBasicTemplatesMap = Maps.newHashMap();
    Map<String, Map<Integer, Map<String, TemplateDelegateNode>>> tempDelTemplatesMap =
        Maps.newHashMap();

    for (SoyFileNode soyFile : soyTree.getChildren()) {
      for (TemplateNode template : soyFile.getChildren()) {

        if (template instanceof TemplateBasicNode) {
          // Case 1: Basic template.
          tempBasicTemplatesMap.put(template.getTemplateName(), (TemplateBasicNode) template);

        } else {
          // Case 2: Delegate template.
          TemplateDelegateNode delTemplate = (TemplateDelegateNode) template;
          String delTemplateName = delTemplate.getDelTemplateName();
          int delPriority = delTemplate.getDelPriority();
          String delPackageName = delTemplate.getDelPackageName();

          Map<Integer, Map<String, TemplateDelegateNode>> tempDivisions =
              tempDelTemplatesMap.get(delTemplateName);
          if (tempDivisions == null) {
            tempDivisions = Maps.newHashMap();
            tempDelTemplatesMap.put(delTemplateName, tempDivisions);
          }

          Map<String, TemplateDelegateNode> tempDivision = tempDivisions.get(delPriority);
          if (tempDivision == null) {
            tempDivision = Maps.newHashMap();
            tempDivisions.put(delPriority, tempDivision);
          }

          if (tempDivision.containsKey(delPackageName)) {
            TemplateDelegateNode prevTemplate = tempDivision.get(delPackageName);
            String prevTemplateFilePath =
                prevTemplate.getNearestAncestor(SoyFileNode.class).getFilePath();
            String currTemplateFilePath =
                delTemplate.getNearestAncestor(SoyFileNode.class).getFilePath();
            if (currTemplateFilePath.equals(prevTemplateFilePath)) {
              throw new SoySyntaxException(
                  String.format(
                      "Found two definitions for delegate template name '%s' in the same delegate"
                          + "package, both in the file %s.",
                      delTemplateName, currTemplateFilePath));
            } else {
              throw new SoySyntaxException(
                  String.format(
                      "Found two definitions for delegate template name '%s' in the same delegate"
                          + "package, in two different files %s and %s.",
                      delTemplateName, prevTemplateFilePath, currTemplateFilePath));
            }
          }
          tempDivision.put(delPackageName, delTemplate);
        }
      }
    }

    // ------ Build the final data structures. ------

    basicTemplatesMap = Collections.unmodifiableMap(tempBasicTemplatesMap);

    ImmutableMap.Builder<String, List<DelegateTemplateDivision>> delTemplatesMapBuilder =
        ImmutableMap.builder();

    for (String delTemplateName : tempDelTemplatesMap.keySet()) {
      Map<Integer, Map<String, TemplateDelegateNode>> tempDivisions =
          tempDelTemplatesMap.get(delTemplateName);

      ImmutableList.Builder<DelegateTemplateDivision> divisionsBuilder = ImmutableList.builder();

      // Note: List should be in decreasing priority order.
      for (int priority = TemplateNode.MAX_PRIORITY; priority >= 0; priority--) {
        if (!tempDivisions.containsKey(priority)) {
          continue;
        }
        Map<String, TemplateDelegateNode> tempDivision = tempDivisions.get(priority);
        DelegateTemplateDivision division = new DelegateTemplateDivision(priority, tempDivision);
        divisionsBuilder.add(division);
      }

      delTemplatesMapBuilder.put(delTemplateName, divisionsBuilder.build());
    }

    delTemplatesMap = delTemplatesMapBuilder.build();
  }