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

io.dinject.javalin.generator.PathSegments Maven / Gradle / Ivy

package io.dinject.javalin.generator;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

class PathSegments {

  static final PathSegments EMPTY = new PathSegments("", Collections.emptySet());

  static PathSegments parse(String fullPath) {

    Set segments = new LinkedHashSet<>();

    StringBuilder path = new StringBuilder();

    if ("/".equals(fullPath)) {
      path.append("/");

    } else {
      for (String section : fullPath.split("/")) {
        if (!section.isEmpty()) {
          path.append("/");
          if (section.startsWith(":")) {
            Segment segment = createSegment(section.substring(1));
            segments.add(segment);
            path.append(segment.path(section));

          } else {
            path.append(section);
          }
        }
      }
    }

    return new PathSegments(path.toString(), segments);
  }

  private static Segment createSegment(String val) {

    String[] metricSplit = val.split(";");
    if (metricSplit.length == 1) {
      return new Segment(metricSplit[0]);
    }

    Set metrics = new HashSet<>(Arrays.asList(metricSplit).subList(1, metricSplit.length));
    return new Segment(metricSplit[0], metrics);
  }

  private final String fullPath;

  private final Set segments;

  private final List withMetrics = new ArrayList<>();

  private final Set allNames = new HashSet<>();

  private PathSegments(String fullPath, Set segments) {
    this.fullPath = fullPath;
    this.segments = segments;
    for (Segment segment : segments) {
      segment.addNames(allNames);
      if (segment.hasMetrics()) {
        withMetrics.add(segment);
      }
    }
  }


  boolean contains(String varName) {
    return allNames.contains(varName);
  }

  List metricSegments() {
    return withMetrics;
  }

  Segment segment(String varName) {

    for (Segment segment : segments) {
      if (segment.isPathParameter(varName)) {
        return segment;
      }
    }
    return null;
  }

  String fullPath() {
    return fullPath;
  }

  static class Segment {

    private final String name;

    /**
     * Metric keys.
     */
    private final Set metrics;

    /**
     * Variable names the metrics map to (Java method param names).
     */
    private final Set metricVarNames;

    Segment(String name) {
      this.name = name;
      this.metrics = null;
      this.metricVarNames = null;
    }

    Segment(String name, Set metrics) {
      this.name = name;
      this.metrics = metrics;
      this.metricVarNames = new HashSet<>();
      for (String key : metrics) {
        metricVarNames.add(combine(name, key));
      }
    }

    void addNames(Set allNames) {
      allNames.add(name);
    }

    boolean hasMetrics() {
      return metrics != null && !metrics.isEmpty();
    }

    private String combine(String name, String key) {
      return name + Character.toUpperCase(key.charAt(0)) + key.substring(1);
    }

    Set metrics() {
      return metrics;
    }

    String name() {
      return name;
    }

    boolean isPathParameter(String varName) {
      return name.equals(varName) || (metrics != null && (metricVarNames.contains(varName) || metrics.contains(varName)));
    }

    /**
     * Reading the value from a segment (rather than directly from pathParam).
     */
    void writeGetVal(Append writer, String varName) {
      if (!hasMetrics()) {
        writer.append("ctx.pathParam(\"%s\")", name);

      } else {
        writer.append("%s_segment.", name);
        if (name.equals(varName)) {
          writer.append("val()");
        } else {
          writer.append("metric(\"%s\")", metricKey(varName));
        }
      }
    }

    private String metricKey(String varName) {

      if (!varName.startsWith(name)) {
        return varName;
      }

      String key = varName.substring(name.length());
      return Character.toLowerCase(key.charAt(0)) + key.substring(1);
    }

    void writeCreateSegment(Append writer) {
      writer.append("      PathSegment %s_segment = PathSegment.of(ctx.pathParam(\"%s_segment\"));", name, name).eol();
    }

    boolean isRequired(String varName) {
      return name.equals(varName);
    }

    String path(String section) {
      if (!hasMetrics()) {
        return section;
      }
      return ":" + name + "_segment";
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy