All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.klojang.templates.TemplateUtils Maven / Gradle / Ivy

The newest version!
package org.klojang.templates;

import org.klojang.check.Check;
import org.klojang.check.Tag;
import org.klojang.collections.WiredList;
import org.klojang.path.Path;
import org.klojang.templates.x.MTag;
import org.klojang.util.Tuple2;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;

import static java.util.Arrays.copyOfRange;
import static java.util.stream.Collectors.toList;
import static org.klojang.check.CommonChecks.empty;
import static org.klojang.check.CommonChecks.in;
import static org.klojang.templates.x.Messages.ERR_BAD_NAME;
import static org.klojang.templates.x.Messages.ERR_NO_SUCH_TEMPLATE;
import static org.klojang.util.CollectionMethods.implode;
import static org.klojang.util.StringMethods.count;
import static org.klojang.util.StringMethods.substringBefore;

/**
 * Utility class extending the functionality of the {@link Template} class.
 *
 * @author Ayco Holleman
 */
public final class TemplateUtils {

  private TemplateUtils() {
    throw new UnsupportedOperationException();
  }

  /**
   * Returns the fully-qualified name of the specified template, relative to the root
   * template. If the template is the root template,
   * {@link Template#ROOT_TEMPLATE_NAME} is returned. Otherwise the fully-qualified name
   * is the {@linkplain org.klojang.path.Path path} from the specified template to the
   * root template, in reverse direction.
   *
   * 
{@code
   * String src = """
   *      ~%%begin:companies%
   *          ~%foo%
   *          ~%%begin:departments%
   *              ~%bar%
   *          ~%%end:departments%
   *      ~%%end:companies%
   *      """;
   * Template t = Template.fromString(src);
   * System.out.println(TemplateUtils.getFQN(t); // "{root}"
   * t = t.getNestedTemplate("companies");
   * System.out.println(TemplateUtils.getFQN(t); // "companies"
   * t = t.getNestedTemplate("departments");
   * System.out.println(TemplateUtils.getFQN(t); // "companies.departments"
   * }
* * @param template the template for which to retrieve the fully-qualified name * @return the fully-qualified name of the template */ public static String getFQN(Template template) { Check.notNull(template); if (template.getParent() == null) { return template.getName(); } WiredList wl = new WiredList<>(); for (Template t = template; t.getParent() != null; t = t.getParent()) { wl.prepend(t.getName()); } return implode(wl, "."); } /** * Returns the fully-qualified name of the specified name. The provided name supposedly * is the name of a variable or nested template inside the specified template. If the * specified template is the root template, this method simply returns the name as-is. * Otherwise it prefixes the template's FQN (and a dot character) to the name. * * @param template the template for which to retrieve the fully-qualified name * @param name the name of a template variable or nested template * @return its fully-qualified name */ public static String getFQN(Template template, String name) { Check.notNull(template, MTag.TEMPLATE); Check.notNull(name, Tag.NAME); return (template.getParent() == null) ? name : getFQN(template) + '.' + name; } /** * Returns a depth-first view of all variable occurrences within the specified template. * The returned {@code List} is created on demand and modifiable. * * @param template the template to collect the variable occurrences from * @return a depth-first view of all variable occurrences within the specified template */ public static List getAllVariableOccurrences(Template template) { Check.notNull(template); ArrayList list = new ArrayList<>(); collectOccurrences(template, list); return list; } private static void collectOccurrences(Template template, ArrayList list) { for (Part part : template.parts()) { if (part instanceof VariablePart vp) { list.add(vp.toOccurrence()); } else if (part instanceof NestedTemplatePart ntp) { collectOccurrences(ntp.getTemplate(), list); } } } /** * Returns the specified template and all templates descending from it. The specified * template will come first in de returned list and the descendant templates are * retrieved in breadth-first order. The returned {@code List} is created on demand and * modifiable. * * @param template the template * @return a {@code List} containing the {@code Template} and its descendants */ public static List